I am trying to implement a Graph type data-structure using a structure node of my own. The node will contain a node location (String), node desciption (as prompt, String) and a vector of pair of other node locations and their corresponding nodes structs. The idea of the vector is to contain the adjacent node, and the adjacent node's location (String). Here is the structure definition:-
struct node
{
string location;
string prompt;
vector<pair<string,node>> op;
void insertNode(const node &b);
void printAll();
};
void node::insertNode(const node &b)
{
op.push_back({b.location,b});
}
void node::printAll()
{
cout<<"\n"<<location<<": "<<this;
cout<<"\n"<<prompt;
for(int i=0;i<op.size();i++)
{
cout<<"\n"<<i+1<<". "<<op[i].first<<": "<<&op[i].second;
}
cout<<endl;
}
As a test, I decided to make a graph. Below is the main() function.
int main()
{
vector<node> nodes;
nodes.resize(5);
nodes[0].location = "point1";
nodes[0].prompt = "This is point1";
nodes[1].location = "point2";
nodes[1].prompt = "This is point2";
nodes[2].location = "point3";
nodes[2].prompt = "This is point3";
nodes[3].location = "point4";
nodes[3].prompt = "This is point4";
nodes[4].location = "point5";
nodes[4].prompt = "This is point5";
nodes[0].insertNode(nodes[1]);
nodes[0].insertNode(nodes[2]);
nodes[1].insertNode(nodes[0]);
nodes[1].insertNode(nodes[2]);
nodes[1].insertNode(nodes[3]);
nodes[2].insertNode(nodes[0]);
nodes[2].insertNode(nodes[1]);
nodes[2].insertNode(nodes[4]);
nodes[3].insertNode(nodes[1]);
nodes[3].insertNode(nodes[4]);
nodes[4].insertNode(nodes[2]);
nodes[4].insertNode(nodes[3]);
for(int i=0;i<nodes.size();i++)
cout<<&nodes[i]<<endl;
for(int i=0;i<nodes.size();i++)
nodes[i].printAll();
return 0;
}
And this is the output I am getting. The issue is the struct addresses when the insertNode() function is called is the same as the address when defined in the main() function. But the struct addresses change when I call the printAll() function. I want to access adjacent nodes via the current node. Something like: node[0].op[0].second.printAll(); but since the memory addresses are different, I am receiving a NULL memory.
/*
0xfb1630
0xfb1688
0xfb16e0
0xfb1738
0xfb1790
point1: 0xfb1630
This is point1
1. point2: 0xfb1890
2. point3: 0xfb1908
point2: 0xfb1688
This is point2
1. point1: 0xfb5ea0
2. point3: 0xfb5f18
3. point4: 0xfb5f90
point3: 0xfb16e0
This is point3
1. point1: 0xfb6400
2. point2: 0xfb6478
3. point5: 0xfb64f0
point4: 0xfb1738
This is point4
1. point2: 0xfb6760
2. point5: 0xfb67d8
point5: 0xfb1790
This is point5
1. point3: 0x6325b0
2. point4: 0x632628
*/
I am not sure what I am doing wrong. My assumption is there must be a mistake in the memory address passed in the function, which is currently passing by reference. But if I change the node inside the pair into a node pointer, then the compiler return "wrong 2nd argument". What is wrong with the approach? Improvements regarding the code (which may deviate from the original question) are welcome as well.
You are storing discrete node
objects in your vector
, not pointers (addresses) to objects. This is why you get different addresse when printing the this
pointer.
void node::insertNode(const node &b)
{
op.push_back({b.location,b});//<-- here, you make a copy of b and store it in op
}
If you want to work with pointers, declare your variables accordingly:
struct node
{
string location;
string prompt;
vector<pair<string,const node*>> op;//<-- pair of string and pointer to node
void insertNode(const node &b);
void printAll();
};
void node::insertNode(const node &b)
{
op.push_back({b.location,&b});//<-- insert address of b
}
void node::printAll()
{
cout<<"\n"<<location<<": "<<this;
cout<<"\n"<<prompt;
for(int i=0;i<op.size();i++)
{
cout<<"\n"<<i+1<<". "<<op[i].first<<": "<<op[i].second;//<-- no need for `&` anymore
}
cout<<endl;
}
Edited to add the const
as per comments