Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating objects in c++

I just waste hours on a simple line causing data loss. I have AnotherClass holding a vector of instances of MyClass. This AnotherClass instantiates objects of MyClass the following way:

 AnotherClass::AnotherClass(){            
      MyClass myObject(...);
      myVector.push_back(&myObject);
 }

The address of myObject is afterwards pushed into a vector (with other instances of MyClass), like written in the code. When I start using instances of AnotherClass I notice the values of MyClass were lost (completely random). When I change the code to:

 AnotherClass::AnotherClass(){            
      MyClass* myObject = new MyClass(...);
      myVector.push_back(myObject);
 }

I don't have data loss.

Can somebody be so kind to explain me why the second way of creating objects doesn't lead to a loss of data? (without referencing me to books of 1.000 pages)

like image 702
Drizzt Avatar asked Jul 19 '26 04:07

Drizzt


2 Answers

Simple. The first version creates a local variable on the stack, which gets destroyed automatically when it goes out of scope (at the end of the function)

Your vector just contains a pointer to where the object used to be.

The second version creates an object on the heap, which will live until you eventually delete it.

like image 77
benjymous Avatar answered Jul 21 '26 18:07

benjymous


The reason is RAII.

In the first snippet you declare an object in the scope of your method/constructor. As soon this scope ends, this is the case when method is finished, your object gets out-of-scope and becomes cleaned for you (this means that its desctructor is called). Your vector now still holds pointers to your already cleaned and thus invalid objects, thats the reason why you get garbage.

In the second snippter, your object are contained on the heap. They wont become cleaned / destroyed unless you call delete myObj;. Thats the reason why they remain valid even after the method has finsihed.

You can solve this on multiple ways:

  • Declare your vector as std::vector<MyClass> (notice, not a pointer type)
  • Keep your second snippet but make sure to delete all elements of your vector once your done
  • Use smart pointers if you dont want to cleanup your objects by your own (e.g std::shared_ptr or std::unique_ptr)
like image 42
Sebastian Hoffmann Avatar answered Jul 21 '26 20:07

Sebastian Hoffmann



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!