Reputation: 41
I have recently started programming in C++ (Have done in Java). I am having issues with a class variable not retaining its values.
bt_builder.h
class BtreeBuilder{
BtreeNode *root; //will point to root of the tree
public:Status insertBuilderKey(KeyId);
.....
}
bt_builder.cpp
Status BtreeBuilder::insertBuilderKey(KeyId k){
....
BtreeIndex newroot ;
newroot.insertKey(Ld.getKey(0),0,left,right);
root = &newroot;
printnode(root);// prints correct values
....
}
bt_main.cpp
int main()
{
BtreeBuilder *btb = new BtreeBuilder();
btb->insertBuilderKey(1);//inside this method it has printed values corretly
btb->printroot();//now it is printing garbage values for root node it seems that the value which was set for root inside the method is no longer there
}
So my question is why does it does not retains value of root
outside the method, even when it is a class variable?
What's the solution of this issue.
Upvotes: 0
Views: 2154
Reputation: 36597
A local variable is of automatic storage duration by default, and ceases to exist when the scope is exited (e.g. returning from the function).
Keeping its address (in a pointer) therefore results in a dangling pointer - a pointer that points to something that no longer exists. Dereferencing that pointer causes undefined behaviour.
This is completely different from Java, which relies on the garbage detector detecting when an object is no longer referenced, and destroying it - allowing to to be used for as long as a reference to it exists.
Upvotes: 1
Reputation: 122133
When you try to insert the tree:
Status BtreeBuilder::insertBuilderKey(KeyId k){
....
BtreeIndex newroot ;
newroot.insertKey(Ld.getKey(0),0,left,right);
root = &newroot;
printnode(root);// prints correct values
....
}
...you create a BtreeIndex newroot
and make the member root
point to it. Printing root
works fine, but when the function returns the newroot
gets deleted and root
points to nirvana.
If you use it properly, C++ takes care for you of deleting stuff. However, if you want to take control of the life-time of the object, you have to use new
and delete
. E.g.
Status BtreeBuilder::insertBuilderKey(KeyId k){
....
root = new BtreeIndex();
root->insertKey(Ld.getKey(0),0,left,right);
printnode(root);// prints correct values
....
}
On the other hand, if anyhow the BtreeBuilder
"owns" the BtreeIndex
why not store the object instead of the pointer? I.e.
BtreeIndex root;
Status BtreeBuilder::insertBuilderKey(KeyId k){
....
root.insertKey(Ld.getKey(0),0,left,right);
....
}
Upvotes: 0
Reputation: 165
You have class memeber BtreeNode root;
and you assign it value from a variable on stack: BtreeIndex newroot
. This variable will be destroyed when code exits the scope (exits insertBuilderKey(KeyId k){...}
function. If you need to assign new root, create it in heap BtreeIndex newroot = new BtreeIndex()
and move on. Don't forget to delete what's needed afterwards.
Upvotes: 1
Reputation: 619
BtreeIndex newroot ;
in BtreeBuilder::insertBuilderKey
created a BtreeIndex
on the stack, but the stackframe holding that variable is destroyed once the method is done and thus your variable is destroyed as well.
You need to create the BtreeIndex
on the heap: BtreeIndex* newroot = new BtreeIndex();
See http://www.learncpp.com/cpp-tutorial/79-the-stack-and-the-heap/ for further information.
Upvotes: 4