Reputation: 3496
Edit changed code to be a minimal reproducible example
So Im basically having a struct and a function that creates instances of this struct, pushes them into a std::vector<Node>
and then returns it.
#include <iostream>
#include <vector>
struct Node {
int value;
Node *left;
Node *right;
};
Node createNodeFamily(Node child1, Node child2) {
Node parent;
parent.value = child1.value + child2.value;
parent.left = &child1;
parent.right = &child2;
return parent;
}
std::vector<Node> f(std::vector<Node>& nodes) {
std::vector<Node> l;
Node parent = createNodeFamily(nodes[0], nodes[1]);
l.push_back(parent);
Node r = l[0];
std::cout << "correct value of left child node: " << r.left->value << std::endl;
std::cout << "correct value of right child node: " << r.right->value << std::endl;
return l;
}
int main() {
Node child1;
child1.value = 2;
Node child2;
child2.value = 1;
std::vector<Node> children;
children.push_back(child1);
children.push_back(child2);
std::vector<Node> p = f(children);
Node parent = p[0];
//std::cout << parent.value << std::endl;
std::cout << "wrong value of left child node: " << parent.left->value << std::endl;
std::cout << "wrong value of right child node: " << parent.right->value << std::endl;
return 0;
}
The output in my case:
Printed inside the function:
>> correct value of left child node: 2
>> correct value of right child node: 1
Printed outside the function:
>> wrong value of left child node: 1875944288
>> wrong value of right child node: 16717313
So the struct has the two attributes left
and right
which are pointers that point to a address of a child Node. When Im reading the values of those pointera printing them inside the testFunction
they are correct.
But when I return them, and print them they are holding seemingly random numbers.
Upvotes: 0
Views: 232
Reputation: 1260
Storing pointers to stack variables is generally a recipe for disaster as you've found. When you use new
the pointers aren't to stack variables anymore (they're being stored on the heap), but still are a bit sketchy since you'll need to make sure to delete
the pointers when you're done, and there will likely be performance implications since your nodes will be scattered around in memory.
Normally when dealing with vectors with elements that reference other elements, I'll try to store index values rather than pointers. Consider the following:
struct Node {
int value;
size_t left_index;
size_t right_index;
};
Node createNodeFamily(size_t child1_index, size_t child2_index, std::vector<Node>& nodes) {
Node parent;
parent.value = nodes[child1_index].value + nodes[child2_index].value;
parent.left_index = child1_index;
parent.right_index = child2_index;
return parent;
}
then anytime you need to access a node you'd use nodes[index]
instead of just *node
.
Upvotes: 1
Reputation: 3496
A solution is to not create the pointers using &
but by creating Node using new
(changes made inside the createNodeFamily
function):
Node createNodeFamily(Node child1, Node child2) {
Node parent;
parent.value = child1.value + child2.value;
parent.left = new Node;
parent.left->value = child1.value;
parent.right->value = child2.value;
return parent;
}
Upvotes: 0