Reputation: 3
class ParentClass {
protected:
int* intArray;
public:
~ParentClass(){
delete [] intArray;
}
};
class ChildClass : public ParentClass {
public:
ChildClass() : ParentClass() {
intArray = new int[5];
}
};
int main(int argc, const char * argv[]) {
ChildClass child;
child.~ChildClass(); //This line crashes the program. why??
}
The specific error that it throws: initialization(37640,0x7fff78623300) malloc: * error for object 0x100100aa0: pointer being freed was not allocated * set a breakpoint in malloc_error_break to debug
The pointer is referencing intArray
declared in ParentClass
, the error states that the memory was not allocated, but it was allocated in the ChildClass
constructor.
Can someone explain what process this is going through to generate this error?
Upvotes: 0
Views: 2182
Reputation: 916
You are experiencing undefined behavior. From the C++ standard:
Once a destructor is invoked for an object, the object no longer exists; the behavior is undefined if the destructor is invoked for an object whose lifetime has ended (3.8). [Example: if the destructor for an automatic object is explicitly invoked, and the block is subsequently left in a manner that would ordinarily invoke implicit destruction of the object, the behavior is undefined.
Upvotes: 1
Reputation: 73386
child
is a local object of main()
. It's automatically destroyed when leaving the scope of the function.
Unfortunately you manually destroy it before leaving the function by calling explicitly the detructor. So it gots destroyed two times (one too much) : the second times it crashes !
You don't have to destroy local objects. Explicit destruction is only needed for pointers when you allocate dynamically objects with new
. But then you should delete them using delete
.
The explicit call of the destructor is only relevant in a very rare case: when you want to reuse the storage of a dynamic object with a placement-new.
Remark: in ParentClass
you should initialize intArray
to nullptr. This would make sure that if accidentally no allocation would be done, delete
wouldn't try to deallocate an unititalized pointer.
Upvotes: 0
Reputation: 155250
The problem isn't that intArray
isn't allocated, it's that you're deallocating it twice.
ChildClass child;
instantiates the ChildClass
instance and calls the default constructor which allocates intArray
fine, no problem there.
Then your code explicitly calls the destructor (something you generally never need to do for stack-allocated/automatic objects).
Then the compiler inserts another call to the destructor during scope cleanup, which causes delete[]
to be called a second time, which is incorrect, and causes the crash. Your debugger probably reports the last line of the function (where your explicit destructor call is) when it really should point to the closing brace.
To be sure, set a breakpoint in your destructor and run your program and see how many times it's hit.
Upvotes: 2