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

C++

C++ Problem Overview


Foo* set = new Foo[100];
// ...
delete [] set;

You don't pass the array's boundaries to delete[]. But where is that information stored? Is it standardised?

C++ Solutions


Solution 1 - C++

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.

Solution 2 - C++

ONE OF THE approaches for compilers is to allocate a little more memory and to store a count of elements in a 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 the first sizeof(int) bytes

*temp = 4;

and set i

i = temp + 1;

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

And deletion

delete[] i;

will be processed in the following way:

int *temp = i - 1;
int numbers_of_element = *temp; // = 4
... call destructor for numbers_of_element elements
... that are stored in temp + 1, temp + 2, ... temp + 4 if needed
free (temp)

Solution 3 - C++

The information is not standardised. However in the platforms that I have worked on this information is stored in memory just before the first element. Therefore you could theoretically access it and inspect it, however it's not worth it.

Also this is why you must use delete [] when you allocated memory with new [], as the array version of delete knows that (and where) it needs to look to free the right amount of memory - and call the appropriate number of destructors for the objects.

Solution 4 - C++

It's defined in the C++ standard to be compiler specific. Which means compiler magic. It can break with non-trivial alignment restrictions on at least one major platform.

You can think about possible implementations by realizing that delete[] is only defined for pointers returned by new[], which may not be the same pointer as returned by operator new[]. One implementation in the wild is to store the array count in the first int returned by operator new[], and have new[] return a pointer offset past that. (This is why non-trivial alignments can break new[].)

Keep in mind that operator new[]/operator delete[]!=new[]/delete[].

Plus, this is orthogonal to how C knows the size of memory allocated by malloc.

Solution 5 - C++

Basically its arranged in memory as:

[info][mem you asked for...]

Where info is the structure used by your compiler to store the amount of memory allocated, and what not.

This is implementation dependent though.

Solution 6 - C++

This isn't something that's in the spec -- it's implementation dependent.

Solution 7 - C++

Because the array to be 'deleted' should have been created with a single use of the 'new' operator. The 'new' operation should have put that information on the heap. Otherwise, how would additional uses of new know where the heap ends?

Solution 8 - C++

This is a more interesting problem than you might think at first. This reply is about one possible implementation.

Firstly, while at some level your system has to know how to 'free' the memory block, the underlying malloc/free (which new/delete/new[]/delete[] generally call) don't always remember exactly how much memory you ask for, it can get rounded up (for example, once you are above 4K it is often rounded up to the next 4K-sized block).

Therefore, even if could get the size of the memory block, that doesn't tell us how many values are in the new[]ed memory, as it can be smaller. Therefore, we do have to store an extra integer telling us how many values there are.

EXCEPT, if the type being constructed doesn't have a destructor, then delete[] doesn't have to do anything except free the memory block, and therefore doesn't have to store anything!

Solution 9 - C++

It is not standardized. In Microsoft's runtime the new operator uses malloc() and the delete operator uses free(). So, in this setting your question is equivalent to the following: How does free() know the size of the block?

There is some bookkeeping going on behind the scenes, i.e. in the C runtime.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVolkerKView Question on Stackoverflow
Solution 1 - C++Peter KühneView Answer on Stackoverflow
Solution 2 - C++AvtView Answer on Stackoverflow
Solution 3 - C++DaeminView Answer on Stackoverflow
Solution 4 - C++MSNView Answer on Stackoverflow
Solution 5 - C++Francisco SotoView Answer on Stackoverflow
Solution 6 - C++jeffmView Answer on Stackoverflow
Solution 7 - C++Joel CoehoornView Answer on Stackoverflow
Solution 8 - C++Chris JeffersonView Answer on Stackoverflow
Solution 9 - C++AndreView Answer on Stackoverflow