Violet Giraffe Violet Giraffe - 2 months ago 5
C++ Question

Why does calling delete instead of delete[] on an array of class objects cause heap corruption?

Consider the code:

class A {
virtual ~A() {}

class B : public A {
~B() {}

void main ()
A * array = new A[100];
delete array;

On Windows (MSVC 2010), it causes exception because
, which then indicates the heap was corrupted. How and why does this happen?

I indeed realize
should be called here, and of course then there is no problem. But why does
cause heap corruption? As far as I know, it should call a destructor for the first object (
) and then free the whole block. What happens in reality?

Note: if class
only has default destructor, i.e. I don't declare its destructor at all, the exception does not occur. Regardless of whether the destructor is virtual or not. Both in debug and release build.

P. S. yes I know this is undefined behavior.


It is undefined behavior to call delete on a pointer created with new[]. The basic issue is that when you call new[] it needs to allocate extra space to store the number of elements in the array, so that when you call delete [] it knows how many elements to destroy.

The library will allocate space for the management data in addition to the needed space for the real objects. It will then perform all initialization and return a pointer to the first element, which is not aligned with the block of memory retrieved from the OS.

^       ^
|       \_ pointer returned by new[]
\_ pointer returned by the allocator

On the other hand, new and delete don't store any extra information.

When you call delete[] it moves the pointer back, reads the count, calls the destructors and deallocates using the original pointer. When you call delete, it calls the destructor for the single object and passes the pointer back to the allocator. If the pointer was created through a call to new[], then the pointer that is returned to the allocator is not the same pointer that was allocated and the deallocation fails.