How does delete[] know it's an array?

One question that the answers given so far don't seem to address: if the runtime libraries (not the OS, really) can keep track of the number of things in the array, then why do we need the delete[] syntax at all? Why can't a single delete form be used to handle all deletes?

The answer to this goes back to C++'s roots as a C-compatible language (which it no longer really strives to be.) Stroustrup's philosophy was that the programmer should not have to pay for any features that they aren't using. If they're not using arrays, then they should not have to carry the cost of object arrays for every allocated chunk of memory.

That is, if your code simply does

Foo* foo = new Foo;

then the memory space that's allocated for foo shouldn't include any extra overhead that would be needed to support arrays of Foo.

Since only array allocations are set up to carry the extra array size information, you then need to tell the runtime libraries to look for that information when you delete the objects. That's why we need to use

delete[] bar;

instead of just

delete bar;

if bar is a pointer to an array.

For most of us (myself included), that fussiness about a few extra bytes of memory seems quaint these days. But there are still some situations where saving a few bytes (from what could be a very high number of memory blocks) can be important.


The compiler doesn't know it's an array, it's trusting the programmer. Deleting a pointer to a single int with delete [] would result in undefined behavior. Your second main() example is unsafe, even if it doesn't immediately crash.

The compiler does have to keep track of how many objects need to be deleted somehow. It may do this by over-allocating enough to store the array size. For more details, see the C++ Super FAQ.


Yes, the OS keeps some things in the 'background.' For example, if you run

int* num = new int[5];

the OS can allocate 4 extra bytes, store the size of the allocation in the first 4 bytes of the allocated memory and return an offset pointer (ie, it allocates memory spaces 1000 to 1024 but the pointer returned points to 1004, with locations 1000-1003 storing the size of the allocation). Then, when delete is called, it can look at 4 bytes before the pointer passed to it to find the size of the allocation.

I am sure that there are other ways of tracking the size of an allocation, but that's one option.