Halil ─░brahim Azak Halil ─░brahim Azak - 3 days ago 5
C++ Question

Deleting an array of objects

Here is the code:

class A {
private:
int *anArr;
int id;
public:
A() {
id = 0;
anArr = new int[10];
}
A(int i) {
id = i;
anArr = new int[10];
}
~A() {
delete[] anArr;
std::cout << "Class A id : " << id << " destructor" << std::endl;
}
};

class B {
private:
A *anArr;
public:
B() {
anArr = new A[10];
}
~B() {
std::cout << "Class B destructor" << std::endl;
delete[] anArr;
}
void changeAnElement() {
anArr[2] = A(1);
anArr[2] = A(2);
}
};

int main()
{
B b;
b.changeAnElement();

return 0;
}


Output:

Class A id : 1 destructor
Class A id : 2 destructor
Class B destructor
Class A id : 0 destructor
Class A id : 0 destructor
Class A id : 0 destructor
Class A id : 0 destructor
Class A id : 0 destructor
Class A id : 0 destructor
Class A id : 0 destructor
// Gives heap error here


So if I'm not wrong, when I change an element of object array it does not call destructor.
My first question is what happens to old object at the changed index? Does the array in it leak? I thought that I need to call destructor myself to prevent memory leak but it gives heap error.
Second question is I'm getting heap error (
Expression: _CrtlsValidHeapPointer(block)
) when destructor of the changed object called. I have no idea why, it works fine for the ones created in constructor.
Thanks!

Answer

My first question is what happens to old object at the changed index?

An object in an array never goes anywhere. The "old" object remains in that index. You invoke the assignment operator on that object. The assignment operator modifies the object.

Does the array in it leak?

The array that the object pointed to before the assignment does leak, yes.

I thought that I need to call destructor myself to prevent memory leak

You created the object with new[], so you do need to call delete[], which indeed calls the destructors.

but it gives heap error

That's because you forgot to follow the rule of 3 (or of 5).

anArr[2] contains the same pointer that the temporary A(2) contained, but since the destructor of the temporary has already run, it has already deleted the array and the destructor of anArr[2] then tries to delete it again. Which is one of the things that must not be done.


Conclusions:

  • When you do manual memory management, follow the rule of 3
  • Don't do manual memory management. Use std::vector or std::array here instead.
Comments