meelo
meelo

Reputation: 41

C++ class variable does not retain values

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

Answers (4)

Peter
Peter

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

463035818_is_not_an_ai
463035818_is_not_an_ai

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

rezdm
rezdm

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

Ch33f
Ch33f

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

Related Questions