Self referential Structure - c++

I am writing 2 codes for self referential structures :
1st:
struct node
{
int a;
struct node *link;
};
int main()
{
struct node n;
n.a = 5;
cout<< n.a << "\t" ;
cout << n.link ;
return 0;
}
Output : ̀ 5 0x40185b`
2nd:
struct node{
int a;
struct node *link;
};
int main(){
struct node n;
n.a = 5;
cout << n.a << "\t";
cout << *n.link ;
return 0;
}
Output: error:link was not declared in this scope.
Please tell me what is really happening in the code??
Why does a garbage value is thrown??
How can I initialize a self referential structure pointer??

I suppose that's what you want to do:
int main(){
struct node n;
n.a = 5;
n.link = NULL; // initialize the link
cout << n.a << "\t";
cout << n.link;
return 0;
}
*(n.link) will only be valid if n.link points to a valid node object.
And cout << *(n.link); will only be valid if you declare an operator<< for node (cout << n.link; is valid as it outputs the adress, not the value).
For instance, this would work much better:
#include <iostream>
struct node{
int a;
node *link; // Note: no need to prefix with struct
};
std::ostream& operator<<( std::ostream& str, const struct node& n )
{
str << n.a << "\t -> ";
if ( n.link )
str << *n.link;
else
str << "NULL";
return str;
}
int main(){
node n1; // Note: no need to prefix with struct
node n2; // Note: no need to prefix with struct
n1.a = 5;
n1.link = &n2;
n2.a = 6;
n2.link = NULL;
cout << n1;
return 0;
}
It outputs 5 -> 6 -> NULL

Related

C++ Struct Lifetime And Scope With Pointers

Consider the following example:
#include<iostream>
#include <vector>
using namespace std;
const int UN_INITIALIZED = -1;
struct Node
{
Node *rightNode = nullptr;
int data = UN_INITIALIZED;
};
struct Test {
Test()
{
root.data = 1;
}
void link_nodes()
{
Node n;
cout << "address : " << &n << endl;
n.data = 5;
root.rightNode = &n;
} // n is destroyed? n.rightNode shouldn't be defined?
Node root;
};
int main()
{
Test t;
t.link_nodes();
// out of scope?
cout << t.root.rightNode->data << endl; // This return -1
return 0;
}
When running the following example I get a value of -1 which is the default uninitialized value of Node::data. in link_nodes() shouldn't n be destroyed after the function call ends and calling ->data should give an error or seg fault?
Also when I try creating a different scope in the main function the results tend to be correct :
int main()
{
Node root;
{
Node n;
n.data = 55;
root.rightNode = &n;
} // n died?
cout << root.rightNode->data << endl; //gives 55
return 0;
}
The scope of the variable n is the block scope of the member function link_nodes.
void link_nodes()
{
Node n;
cout << "address : " << &n << endl;
n.data = 5;
root.rightNode = &n;
}
After exiting the function the variable n having automatic storage duration will not be alive. As a result the pointer root.rightNode will be invalid. Dereferencing the pointer results in undefined behavior.
The same problem exists in the second program
Node root;
{
Node n;
n.data = 55;
root.rightNode = &n;
} // n died?
cout << root.rightNode->data << endl;
Again the variable n is not alive after passing the control outside the compound statement where it is defined. So the pointer root.rightNode will be invalid.

I can't somehow sort my linked queue nodes with a bubble sort algorithm

So, I was asked by my instructor to make a node containing a few variables and sort it by taking the hourlySalary variable as reference for each code. However, there seems to be a problem with the outputs. It isn't sorting the nodes at all. I tried to fix it for a while and gave up. Looked up some sources on the internet but still no luck. I am guessing that the problem is somewhere in the swapping function or the bubble sort function.
Here is my code.
#include <iostream>
using namespace std;
class myNumberIsEleven{
private:
struct linkedlist{
string firstName;
string lastName;
unsigned int age;
char gender;
int hourlySalary;
linkedlist *linker;
}*Ptr,*curPtr;
public:
int counter=0;
myNumberIsEleven(){
Ptr=NULL;
}
void printList(){
curPtr=Ptr;
while(curPtr!=NULL){
cout << curPtr->firstName << " " << curPtr->lastName << endl << curPtr->age << endl << curPtr->gender << endl << curPtr->hourlySalary << endl << "=====" << endl;
curPtr=curPtr->linker;
}
}
void add(int salary,string name,string lastname,int ageisjustanumber,char Gender){
linkedlist *newPtr = new linkedlist;
newPtr->hourlySalary = salary;
newPtr->firstName = name;
newPtr->lastName = lastname;
newPtr->gender = Gender;
newPtr->age = ageisjustanumber;
newPtr->hourlySalary = salary;
newPtr->linker = Ptr;
Ptr = newPtr;
counter++;
}
void Swap(linkedlist* a,linkedlist* b){
string temp_firstName;
string temp_LastName;
unsigned int temp_Age;
char temp_Gender;
int temp_hourlySalray;
temp_firstName = a->firstName;
temp_LastName = a->lastName;
temp_Age = a->age;
temp_Gender = a->gender;
temp_hourlySalray = a->hourlySalary;
a->firstName = b->firstName;
a->lastName = b->lastName;
a->age = b->age;
a->gender = b->gender;
a->hourlySalary = b->hourlySalary;
b->firstName = temp_firstName;
b->lastName = temp_LastName;
b->age = temp_Age;
b->gender = temp_Gender;
b->hourlySalary = temp_hourlySalray;
}
void bubbleSort(){
for(linkedlist* i=Ptr;i->linker != NULL;i=i->linker){
for(linkedlist* j = i->linker;j!=NULL;j=j->linker){
if(i->hourlySalary > i->hourlySalary){
Swap(i,j);
}
}
}
printList();
}
/*
void bubbleSort(int arr[], int n)
{
int i, j;
for (i = 0; i < n-1; i++)
// Last i elements are already in place
for (j = 0; j < n-i-1; j++)
if (arr[j] > arr[j+1])
swap(&arr[j], &arr[j+1]);
}
*/
};
int main()
{
myNumberIsEleven myNameIsBerkan;
myNameIsBerkan.add(1000,"berkan","iwontgivemysurname",21,'M');
myNameIsBerkan.add(2100,"ah","be",31,'F');
myNameIsBerkan.add(50,"uhmmm","something",10,'M');
myNameIsBerkan.add(69000,"elon","musk",44,'M');
myNameIsBerkan.bubbleSort();
return 0;
}

How to print the lead of A* algorithm

-I wrote a program to find the shortest path from a source node to a target node. Everything is fine, the program found the shortest path. But i have a problem, that is not able to print or get each node in the path. I tried many ways but no result. Hope anyone can help me, thanks everyone.
///////////////////////////////
#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>
typedef struct Node
{
int vertex;
int g;
int h;
int f;
Node* parent;
Node(int vertex)
{
this->vertex = vertex;
this->g = 0;
this->h = 0;
this->f = 0;
this->parent=NULL;
}
Node(int vertex,int g, int h, int f,Node*parent)
{
this->vertex = vertex;
this->g = g;
this->h = h;
this->f = f;
this->parent = parent;
}
}Node;
struct Edge
{
int source;
int dest;
int g;
int h;
};
struct comp
{
bool operator()(const Node* lhs, const Node* rhs) const {
return lhs->f < rhs->f;
}
};
std::vector<Node*>openList;
std::vector<Node*>closeList;
Node* startPos;
Node* endPos;
static const int WeightW = 10;
class Graph
{
public:
std::vector<std::vector<Edge>>adjlist;
Graph(const std::vector<Edge>& edges, int N)
{
adjlist.resize(N);
for (auto &edge:edges)
{
adjlist[edge.source].push_back(edge);
}
}
};
int isContains(std::vector<Node*>* Nodelist, int vertex);
void printPath(Node*node);
void findShortestPath(const Graph& grap,Node* start,Node* end, int N)
{
Node* node;
openList.push_back(start);
while (openList.size()>0)
{
node = openList[0];
closeList.push_back(node);
openList.erase(openList.begin());
std::cout << "start" << std::endl;
int u = node->vertex;
std::cout << "V: " << u << " g :" << node->g << std::endl;
std::cout << "continous" << std::endl;
for (auto v : grap.adjlist[u])
{
if (v.dest == end->vertex)
{
std::cout << "FindNode " << v.dest << std::endl;
printPath(node);
return;
}
if (isContains(&closeList, v.dest) == -1)
{
if (isContains(&openList, v.dest) == -1)
{
int vertex = v.dest;
std::cout <<"V: "<< vertex << std::endl;
int h = v.h;
int currentg = node->g + v.g;
int f = currentg + h;
std::cout <<"vertext: "<<vertex<< " h: " << h << " g: " << currentg << " f: " << f << std::endl;
Node* newNode = new Node(vertex, currentg, h, f,node->parent);
openList.push_back(newNode);
}
}
}
std::cout<<"Close: ";
for (size_t i = 0; i < closeList.size(); i++)
{
std::cout << closeList[i]->vertex << " ";
}
std::cout << std::endl;
sort(openList.begin(), openList.end(),comp());
std::cout << "Open: ";
for (size_t i = 0; i < openList.size(); i++)
{
std::cout << openList[i]->vertex << " ";
}
std::cout << std::endl;
std::cout << "end" << std::endl;
std::cout << std::endl;
}
}
void printPath(Node* node)
{
std::cout << std::endl;
if (node->parent != NULL)
printPath(node->parent);
std::cout << node->vertex << " ";
}
int isContains(std::vector<Node*>* Nodelist,int vertex)
{
for (int i = 0; i < Nodelist->size(); i++)
{
if (Nodelist->at(i)->vertex== vertex)
{
return i;
}
}
return -1;
}
int main()
{
//{Node,Node,G,H}
//Firt Node
//second Node
//G is the movement cost to move from the starting point to a given square on the grid
// following the path generated to get there
//H is the estimated movement cost to move from that given square on the grid to the final destination
std::vector<Edge>edges =
{
{0,1,5,17},
{0,2,5,13},
{1,0,5,16},
{1,3,3,16},
{1,2,4,13},
{2,0,5,16},
{2,1,4,17},
{2,3,7,16},
{2,4,7,16},
{2,7,8,11},
{3,2,7,13},
{3,7,11,11},
{3,10,16,4},
{3,11,13,7},
{3,12,14,10},
{4,2,7,13},
{4,5,4,20},
{4,7,5,11},
{5,4,4,16},
{5,6,9,17},
{6,5,9,20},
{6,13,12,7},
{7,3,11,16},
{7,4,5,16},
{7,8,3,10},
{8,7,3,11},
{8,9,4,8},
{9,8,4,10},
{9,13,3,7},
{9,15,8,0},
{10,3,16,16},
{10,11,5,7},
{10,13,7,7},
{10,15,4,0},
{11,3,13,16},
{11,10,5,4},
{11,12,9,10},
{11,14,4,5},
{12,3,14,16},
{12,11,9,7},
{12,14,5,5},
{13,9,3,8},
{13,10,7,4},
{13,15,7,0},
{14,11,4,7},
{14,12,5,10},
{15,9,8,8},
{15,10,4,4},
{15,13,7,7},
};
int n = edges.size();
Graph grap(edges, n);
//std::cout << h << std::endl;
Node* start = new Node(0);
Node* end = new Node(15);
findShortestPath(grap, start, end, n);
//Astar astar;
//Node* startPos = new Node(5, 1);
//Node* endPos = new Node(1, 8);
//astar.printMap();
//astar.search(startPos, endPos);
//cout << endl;
//astar.printMap();
system("pause");
return 0;
}
Your program doesn't find the shortest path. It gives the wrong output. (you're on the right track though)
I will assume you are trying to find the shortest path by using BFS. Let's take a look at line 113:
sort(openList.begin(), openList.end(),comp());
Here you're sorting your BFS queue (vector in your case) and thus destroying the right order.
Delete that line.
Congrats, now your program finds the shortest path!
Next, as I understand, for each node you branch into, you remember which node you came from in order to backtrack the path once you reach the destination or final node.
In line 102:
Node* newNode = new Node(vertex, currentg, h, f,node->parent);
you are assigning the new node's grandparent instead of parent. Change that line to
Node* newNode = new Node(vertex, currentg, h, f,node);
Now your printPath function works properly and prints the right path. (just add the target node)
Anyways, your code has a lot of space for improvements. Check out other implementations online and try to see if you can code it as short and clean for practice. Good luck!

EXC_BAD_ACCESS pointer C++

This is by far the most frustrating error I have come across while programming in C++. Here is the code I am trying to run. Every time I run it, it gives me bad access error and when I try to debug it with LLDB, it shows that value of every member in end = 0 and gives the bad access pointer error. Please let me know what's the solution to the current problem. I have been stuck on this for a while now and I come across this error every now and then so any debugging tips would be appreciated.
struct edge;
struct node
{
int id;
double longitude;
double latitude;
double distance;
string state;
string name;
vector<edge*>r;
int prio;
};
struct edge
{
string name, type;
double dist;
node* x;
node* y;
void print()
{
cout << name << " " << type << " "<< dist << " miles" << " from " << x->id << " to " << y->id << endl;
}
edge(node* x, node* y, double dist, string name)
{
this->x = x;
this->y = y;
this->dist = dist;
this->name = name;
}
edge(){};
};
struct route{
int place1;
int place2;
string rt;
string vert;
double lengt;
route(int o, int d, double l,string r ){
place1 = o;
place2 = d;
rt =r;
lengt=l;
}
};
struct compPair
{
bool operator()(node* a, node* b)
{
return a->prio > b->prio;
}
};
void SPT(vector<node*> & g, int from, int to){
priority_queue <node *, vector<node*>, compPair> pq;
g[from]->prio = 0;
pq.push(g[from]);
while(!pq.empty()){
node* place1 = pq.top();pq.pop();
for(int i=0;i<place1->r.size();i++){
edge* rd = place1->r[i];
node* place2 = rd->x;
if(place2==place1){
place2=rd->y;
}
if(place2->prio == -2){
place2->prio = place1->prio + rd->dist;
pq.push(place2);
}
else if (place2->prio > (place1->prio + rd->dist)){
place2->prio = place1->prio + rd->dist;
}
}
}
node* beg = g[from];
node* end = g[to];
if(g[from]->prio < 0 || g[to]->prio < 0){
cout <<"Path does not exist";
return;
}
//THIS IS BUGGY CODE, everything works fine without this code //
node* lowp = end;
vector <route*> p;
while(beg!=end){
double reallowp = end->prio;
edge* rtt = end->r[0];
for(int i =0;i<end->r.size();i++){
edge *r = end->r[i];
node* town1 = r->x;
if(town1 == end){
town1 = r->y;
}
if(town1->prio <= reallowp){
reallowp = town1->prio;
lowp = town1;
rtt = r;
}
}
route* e = new route(end->id,lowp->id,rtt->dist,rtt->name);
p.push_back(e);
end=lowp;
}
for(int i=p.size()-1;i>=0;i--){
cout << "From intersection " << p[i]->place2 << "take " << p[i]->rt << " " << p[i]->lengt << " miles to intersection " << p[i]->place1 << endl;
}
}
int main()
{
vector<node*>t = readTown();
readRoad(t);
SPT(t,68,69);
}

Inserting nodes in a Binary Tree recursively?

I am trying to insert nodes in a binary tree recursively, but the code is only doing the root node and it's left and right children. I am trying to figure out how to get past that point.
I have already tried different implementations, using queues, doing level order insert. I believe the problem is due to the fact that in my main function I only call with root, and if that is the problem, how would I go about calling with the left and right childs.
Main Function:
int main() {
treenode* root = new treenode();
for(int a = 1; a < 15; a++) {
insert(root, a);
}
cout << "Height: " << height(root) << endl;
cout << "Printed Tree: " << endl;
for(int a = 0; a <= height(root); a++) {
printGivenLevel(root, a); //Print every level
cout << endl;
}
return 0;
}
Here is my insert function:
void insert(treenode*& node, int val) {
if(node == nullptr) {
node = new treenode(val);
return;
}else{
if(node->left == nullptr) {
insert(node->left, val);
}else{
insert(node->right, val);
}
}
}
A treenode has a value, a left child and right child:
struct treenode {
//The value of the node
int value;
//Pointers to the left and right children
treenode *left, *right;
//Constructor with values;
treenode(int val=0, treenode *l = nullptr, treenode *r = nullptr) : value(val), left(l), right(r) {};
};
I would expect the result to be something like so:
0
1 2
3 4 5 6
7 8 9 10 11 12 13 14
But my actual output is only:
0
1 2
Thanks in advance
... but the code is only doing the root node and it's left and right
children. I am trying to figure out how to get past that point.
I find no error in your treenode::insert, your problem might be in some other code you do not show. For example, you did not provide "height(root)" or "Printed Tree" info. I could not diagnose them.
I have provided some alternatives for various ideas. see "dump()" and "height()" and "size()".
Note: "dump()" is none of pre, in-, or post- order, because the sorted input creates unbalance tree displays (they are worst-case-unbalanced). I found this display the easiest to review.
Perhaps the following will help you diagnose your mistakes. Good luck.
Note the use of "if(false) cout << ...". These are diagnostic output which might provide some insights by enabling them, and / or adding such items to your code.
Did you try your debugger yet?
#include <chrono> // short form names----vvvvvvv
typedef std::chrono::high_resolution_clock HRClk_t; // std-chrono-hi-res-clk
typedef HRClk_t::time_point Time_t; // std-chrono-hi-res-clk-time-point
typedef std::chrono::nanoseconds NS_t; // std-chrono-nanoseconds
using namespace std::chrono_literals; // suffixes like 100ms, 2s, 30us
using std::chrono::duration_cast;
#include <iostream>
using std::cout, std::endl, std::flush;
#include <iomanip>
using std::setw;
namespace DTB
{
class treenode
{
friend class T920_t;
int value; //The value of the node
treenode *left, *right; //Pointers to the left and right children
//Constructor with values;
treenode(int val=0, treenode *l = nullptr, treenode *r = nullptr)
: value(val), left(l), right(r) { ctor('A'); };
void ctor(char kar) {
if (left) left->ctor(kar);
{
if(false) // diagnostic
cout << "\n ctor: " << " " << kar
<< " val: " << setw(3) << value << flush;
}
if(right) right->ctor(kar);
}
void insert ( treenode*& node, int val)
{
if(node == nullptr)
{
node = new treenode(val);
if (false) node->dump(); // diagnostic
return;
}
else
{
if(node->left == nullptr)
{
insert(node->left, val);
if (false) node->dump(); // diagnostic
}
else
{
insert(node->right, val);
if (false) node->dump(); // diaagnostic
}
}
}
int height(int lvl = 1)
{
static int maxHeight = 0;
if (left) left->height (lvl+1);
if(right) right->height (lvl+1);
if (lvl > maxHeight) maxHeight = lvl;
return maxHeight;
}
int size()
{
int count = 1; // this element
if (left) { count += left->size(); };
if(right) { count += right->size(); }
return count;
}
void dump(int lvl=0)
{
if (left) left->dump (lvl+1);
if(right) right->dump (lvl+1);
{
cout << "\n " // << lvl
<< setw(3*lvl) << ' '
<< value << flush;
}
}
}; // class treenode
typedef treenode Node_t; // shorter name for user-defined-type
class T920_t
{
public:
int operator()(int argc, char* argv[]) { return exec(argc, argv); }
private:
int exec(int , char** )
{
int retVal = 0;
Time_t start_ns = HRClk_t::now();
Node_t* root = new Node_t(); // 1st node
for(int v = 1; v < 21; ++v) { // 20 more
root->insert(root, v);
}
cout << "\n\n size : " << root->size() // element count
<< " maxHeight : " << root->height()
<< endl;
dumpAll(root);
for(int v = 1; v < 11; ++v) { // 10 more
root->insert(root, v);
}
cout << "\n\n size : " << root->size() // element count
<< " maxHeight : " << root->height()
<< endl;
dumpAll(root);
auto duration_ns = duration_cast<NS_t>(HRClk_t::now() - start_ns).count();
cout << "\n\n\n T920_t::exec() duration "
<< duration_ns << " ns "
<< " cpluplus vers : " << __cplusplus << std::endl;
return retVal;
}
void dumpAll (Node_t*& node)
{
cout << "\n dumpAll(): ";
node->dump();
cout << endl;
}
}; // class T920_t
} // namespace DTB
int main(int argc, char* argv[]) { return DTB::T920_t()(argc, argv); }
A partial output is:
size : 21 maxHeight : 11
dumpAll():
1
3
5
7
9
11
13
15
17
19
20
18
16
14
12
10
8
6
4
2
0
size : 31 maxHeight : 16
dumpAll():
1
3
...
10
8
6
4
2
0
T920_t::exec() duration 271095 ns cpluplus vers : 201703