How Does Delete[] Know It's an Array

How does delete[] know the size of the operand array?

When you allocate memory on the heap, your allocator will keep track of how much memory you have allocated. This is usually stored in a "head" segment just before the memory that you get allocated. That way when it's time to free the memory, the de-allocator knows exactly how much memory to free.

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

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.

How does delete[] know the size of an array?

It would delete an array of size 9.
It deletes the array pointed to by the pointer.

It is unspecified how the size information is stored, so each compiler may implement it in a different way, but a common way to do it is to allocate an extra block before the array. That is, when you do this:

int* table = new int[5];

it actually allocates an array of 6 integers, and stores the array size in the first element. Then it returns a pointer to the second element. So to find the size, delete[] just has to read table[-1], basically.

That's one common way to do it, but the language standard doesn't specify that it must be done in this way. Just that it has to work.

Another approach might be to use the address of the array as a key into some global hash table. Any method is valid, as long as it produces the correct results.

How does delete[] know the array length in C++?

It can do it however it wants. There are two common ways:

  1. The implementation may use an associative array of allocated pointers mapped to their sizes.

  2. The implementation may allocate a few extra bytes at the beginning to store the size and pass a pointer into the block to the caller.

How does delete[] know how much memory to delete?

First off, i is not "4-byte length". Rather, i is a pointer to an array of four ints.

Next, delete[] doesn't need to know anything, because int has no destructor. All that has to happen is that the memory needs to be freed, which is done by the system's allocator. This is the same situation as with free(p) -- you don't need to tell free how much memory needs to be freed, since you expect it to figure that out.

The situation is different when destructors need to be called; in that case, the C++ implementation does indeed need to remember the number of C++ objects separately. The method for this is up to the implementation, although many compilers follow the popular Itanium ABI, which allows linking together of object code compiled by those different compilers.

There is no way for you to query this information. You should consider dynamic arrays a misfeature of C++; there is essentially no reason to use them*, and you can always do better with some kind of class that manages memory and object separately and individually: Since you'll have to remember the number of array elements anyway, it's much better to encapsulate the size and the allocation in one coherent class, rather than have vague dynamic arrays that you cannot really use without passing extra information along anyway (unless you had self-terminating semantics, but then you'd just be using the extra space for the terminator).

*) And there are at least two standard defects about dynamic arrays that nobody is too bothered to worry about fixing

How does the delete in C++ know how many memory locations to delete

There is only delete operator, free exist only as function. Under C++, you are encouraged to use new/delete over malloc()/free().


There is an internal "magic" in delete operator. When an array is created with new[], the size of array is stored in the metadata at the memory block. delete[] makes use of that information.

All this is of course compiler-, OS-, optimizer- and implementation-dependent.

Why does the delete[] syntax exist in C++?

Objects in C++ often have destructors that need to run at the end of their lifetime. delete[] makes sure the destructors of each element of the array are called. But doing this has unspecified overhead, while delete does not. This is why there are two forms of delete expressions. One for arrays, which pays the overhead and one for single objects which does not.

In order to only have one version, an implementation would need a mechanism for tracking extra information about every pointer. But one of the founding principles of C++ is that the user shouldn't be forced to pay a cost that they don't absolutely have to.

Always delete what you new and always delete[] what you new[]. But in modern C++, new and new[] are generally not used anymore. Use std::make_unique, std::make_shared, std::vector or other more expressive and safer alternatives.

How does delete know the size of derived class from base pointer?

delete and delete[] operators know the size of the allocation, because operators new and new[] save some housekeeping information for them at the time of allocation. It uses the same idea as malloc/free pair, when malloc saves size information that is required for free to do its job.

Figuring out the allocation size is independent of the type for which the memory is allocated. Operators delete and delete[] do not even know the type of the pointer being deleted, because they operate on void pointers.

How does delete[] keep track of the number of elements?

The difference, oversimplified, is this:

delete[] a;

Is correct. All others are incorrect, and will exhibit Undefined Behavior.

Now, in reality, on all the compilers I use daily, delete a; will do the right thing every time. But you should still not do it. Undefined Behavior is never correct.

The free call will also probably do the right thing in the real world, but only because the thing you're freeing doesn't have a non-default destructor. If you tried to free something that was a class with a destructor, for example, it definitely wouldn't work -- the destructor would never be called.

That's one of the big differences (not the only difference) between new/delete and malloc/free -- the former call the constructors and destructors, while the latter meerly allocate and dealocate space.

Incorporating something @Rob said in his now-deleted post:

The simple rule is this: every new[] requires exactly one delete[].
Every new requires exactly one delete. malloc requires free. No
mix-and-match is allowed.

As to the question of how delete[] knows how many elements to delete, please see this response to a previous duplicate question.

How does delete operator work with pointers in c?

Allocators typically hide allocation information just before the pointer in question. The allocation includes that space, but the pointer is moved after it so you don't access/modify it. This is part of why writing to a pointer at a negative index breaks things so badly.

As noted in the comments, your code is broken as written, since you used delete ptr;, not delete[] ptr;; only the latter knows to look for the information needed to destruct the whole array, not just a single element.



Related Topics



Leave a reply



Submit