Search code examples
c++pointersheap-memorydestroy

Storing instance on heap and referencing it from a pointer


Consider the following code:

int cnt = 10;
Object* objects = new Object[cnt];
for(int i = 0; i < cnt; i++) {
    *(objects + i) = Object();
}
//All objects are destroyed here!

All objects are destroyed when the program exits the loop. I think it's because they go out of scope (When I debug it, the destructor of each object is called). How do I store them on the heap but still reference them from the pointer? Why is the following not allowed?

*(objects + i) = new Object(); //not allowed by compiler

UPDATE: It seems that only the temporary objects are being destroyed. I was looking for a way to store these temporary objects on the heap (So that they are not temporary) but that would create a memory leak. The confusion came from the fact that I didn't know that an array of objects is automatically initialized on creation (I came from C#).

Also, what happens when I call delete[] objects? From what I've read, only the pointer is actually deleted. Does that mean I have to cycle through each object and manually delete it? If the object itself also stores other objects (on the heap), do I have to destroy those objects in its destructor method? (Which will automatically be called when I use destroy object).


Solution

  • When you execute *(objects + i) = Object(), a temporary Object instance is created on the stack and passed to the assignment-operator of class Object, with this being objects+i.

    If no assignment-operator is defined, then the default assignment-operator is invoked.

    The default assignment-operator simply copies each one of the member fields of the input object into the corresponding member field of this (in a manner similar to that of a structure-assignment operation).

    So the comment //All objects are destroyed here! is wrong.


    When you execute Object* objects = new Object[cnt], an array of Object instances is created, and the default (empty) constructor is invoked for each one of them.

    So the loop which executes *(objects + i) = Object() for each instance is completely redundant here, because you are essentially creating an Object instance using the default (empty) constructor and then passing it to the assignment-operator, for each instance in the array.