Take the 2-minute tour ×

Alright, I think we all agree that what happens with the following code is undefined, depending on what is passed

void deleteForMe(int* pointer)
     delete[] pointer;

The pointer could be all sorts of different things, and so performing an unconditional delete[] on it is undefined. However, let's assume that we are indeed passing an array pointer

int main()
     int* arr = new int[5];
     return 0;

My question is, in this case where the pointer is an array, who is it that knows this? I mean, from the language/compiler's point of view, it has no idea whether or not arr is an array pointer versus a pointer to a single int. Heck, it doesn't even know whether arr was dynamically created. Yet, if I do the following instead

int main()
     int* num = new int(2);
     return 0;

The OS is smart enough to only delete one int and not go on some type of 'killing spree' by deleting the rest of the memory beyond that point (contrast that with strlen and a non-'\0'-terminated string -- it will keep going until it hits 0).

So whose job is it to remember these things? Does the OS keep some type of record in the background? (I mean, I realise that I started this post by saying that what happens is undefined, but the fact is, the 'killing spree' scenario doesn't happen, so therefore in the practical world someone is remembering)

share|improve this question
+1 for the "killing spree" –  Jay Feb 23 '11 at 23:52
add comment

13 Answers

up vote 63 down vote accepted

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 FAQ Lite.

share|improve this answer
Actually, using delete[] to delete something created with new is exploitable. taossa.com/index.php/2007/01/03/… –  Rodrigo Apr 24 '09 at 13:20
@Rodrigo The link in your comment is broken, but thankfully the wayback machine has a copy of it at replay.web.archive.org/20080703153358/http://taossa.com/… –  David Gardner May 22 '12 at 15:09
add comment

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.

share|improve this answer
"fussiness about a few extra bytes of memory seems quaint these days". Fortunately, to such people bare arrays are also starting to look quaint, so they can just use a vector or boost::array, and forget about delete[] forever :-) –  Steve Jessop Apr 1 '09 at 2:17
+1 for useful background info. –  j_random_hacker Apr 1 '09 at 4:30
add comment

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.

share|improve this answer
+1 - valid point in general except that usually the language runtime is responsible for storing this metadata, not the OS. –  sharptooth Apr 16 '09 at 10:50
What happens to the size of the array or size of an object that has the array defined? Does it show the additional 4 bytes when you do a sizeof on that object? –  Shree Jun 8 '11 at 9:45
No, sizeof shows just the size of the array. If the runtime chooses to implement it w/ the method I described, that's strictly an implementation detail and from a user's perspective, that should be masked. The memory before the pointer does not 'belong' to the user, and doesn't get counted. –  bsdfish Jun 22 '11 at 0:21
More importantly, sizeof will not return the true size of a dynamically allocated array in any case. It can only return sizes known at compile time. –  bdonlan Jul 13 '11 at 18:35
add comment

This is very similar to this question and it has many of the details your are looking for.

But suffice to say, it is not the job of the OS to track any of this. It's actually the runtime libraries or the underlying memory manager that will track the size of the array. This is usually done by allocating extra memory up front and storing the size of the array in that location (most use a head node).

This is viewable on some implementations by executing the following code

int* pArray = new int[5];
int size = *(pArray-1);
share|improve this answer
will this work? In windows & linux we didnt get this working. –  buddingspacer Aug 1 '12 at 8:42
add comment

It doesn't know it's an array, that's why you have to supply delete[] instead of regular old delete.

share|improve this answer
add comment

delete or delete[] would probably both free the memory allocated (memory pointed), but the big difference is that delete on an array won't call the destructor of each element of the array.

Anyway, mixing new/new[] and delete/delete[] is probably UB.

share|improve this answer
add comment

It's up to the runtime which is responsible for the memory allocation, in the same way that you can delete an array created with malloc in standard C using free. I think each compiler implements it differently. One common way is to allocate an extra cell for the array size.

However, the runtime is not smart enough to detect whether or not it is an array or a pointer, you have to inform it, and if you are mistaken, you either don't delete correctly (E.g., ptr instead of array), or you end up taking an unrelated value for the size and cause significant damage.

share|improve this answer
add comment

Agree that the compiler doesn't know if it is an array or not. It is up to the programmer.

The compiler sometimes keep track of how many objects need to be deleted by over-allocating enough to store the array size, but not always necessary.

For a complete specification when extra storage is allocated, please refer to C++ ABI (how compilers are implemented): Itanium C++ ABI: Array Operator new Cookies

share|improve this answer
I only wish every compiler observed some documented ABI for C++. +1 for the link, which I've visited before. Thanks. –  Don Wakefield May 6 '11 at 17:13
add comment

ONE OF THE approaches for compilers is to allocate a little more memory and store count of elements in the head element.

Example how it could be done: Here

int* i = new int[4];

compiler will allocate sizeof(int)*5 bytes.

int *temp = malloc(sizeof(int)*5)

Will store "4" in first sizeof(int) bytes

*temp = 4;

and set i

i = temp + 1;

So i will points to array of 4 elements, not 5.

delete[] i;

will be processed following way

int *temp = i - 1;
int numbers_of_element = *temp; // = 4
... call destructor for numbers_of_element elements if needed
... that a stored in temp + 1, temp + 2, ... temp + 4
free (temp)
share|improve this answer
add comment

I had a similar question to this. In C, you allocate memory with malloc() (or another similar function), and delete it with free(). There is only one malloc(), which simply allocates a certain number of bytes. There is only one free(), which simply takes a pointer as it's parameter.

So why is it that in C you can just hand over the pointer to free, but in C++ you must tell it whether it's an array or a single variable?

The answer, I've learned, has to do with class destructors.

If you allocate an instance of a class MyClass...

classes = new MyClass[3];

And delete it with delete, you may only get the destructor for the first instance of MyClass called. If you use delete[], you can be assured that the destructor will be called for all instances in the array.

THIS is the important difference. If you're simply working with standard types (e.g. int) you won't really see this issue. Plus, you should remember that behavior for using delete on new[] and delete[] on new is undefined--it may not work the same way on every compiler/system.

share|improve this answer
add comment

Semantically, both versions of delete operator in C++ can "eat" any pointer; however, if a pointer to a single object is given to delete[], then UB will result, meaning anything may happen, including a system crash or nothing at all.

C++ requires the programmer to choose the proper version of the delete operator depending on the subject of deallocation: array or single object.

If the compiler could automatically determine whether a pointer passed to the delete operator was a pointer array, then there would be only one delete operator in C++, which would suffice for both cases.

share|improve this answer
add comment

"fussiness about a few extra bytes of memory seems quaint these days". It's not only about a few extra bytes of memory. It also took more time.

share|improve this answer
add comment

You cannot use delete for an array, and you cannot use delete [] for a non-array.

share|improve this answer
I think you mean should not, as your average compiler is not going to detect the abuse. –  Don Wakefield May 6 '11 at 17:21
add comment

Your Answer


