views:

158

answers:

3

In C++, I understand that the delete operator, when used with an array, 'destroys' it, freeing the memory it used. But what happens when this is done?

I figured my program would just mark off the relevant part of the heap being freed for re-usage, and continue on.

But I noticed that also, the first element of the array is set to null, while the other elements are left unchanged. What purpose does this serve?

int * nums = new int[3];
nums[0] = 1;
nums[1] = 2;

cout << "nums[0]: " << *nums << endl;
cout << "nums[1]: " << *(nums+1) << endl;

delete [] nums;

cout << "nums[0]: " << *nums << endl;
cout << "nums[1]: " << *(nums+1) << endl;
+17  A: 

Two things happen when delete[] is called:

  1. If the array is of a type that has a nontrivial destructor, the destructor is called for each of the elements in the array, in reverse order
  2. The memory occupied by the array is released

Accessing the memory that the array occupied after calling delete results in undefined behavior (that is, anything could happen--the data might still be there, or your program might crash when you try to read it, or something else far worse might happen).

James McNellis
+1 for clear and concise answer :-).
Evan Teran
Will a program keep track of allocated memory when a pointer to dynamically allocated memory is changed? e.g., If I increment a pointer, after allocating memory to it using 'new', will using the 'delete' operator on it free up the original block correctly?
ozmo
@ozmo No it will not. You can only delete pointers that you've allocated.@James, "something else far worse might happen" - worse would be (the common case) when you can still access the data, but it's changed to something else - eg `launchNuke = pCountry->clearAndPresentDanger`.
kibibu
+1  A: 

The reasons for it being NULL are up to the heap implementation.

Some possible reasons are that it is using the space for it's free-space tracking. It might be using it as a pointer to the next free block. It might be using it to record the size of the free block. It might be writing in some serial number for new/delete debug tracking.

It could just be writing NULL because it feels like it.

Zan Lynx
I was still wondering what rhyme or reason there was to this undefined behavior, so this was helpful too, thanks.
ozmo
A: 

Whenever someone says int* nums = new int[3], the runtime system is required to store the number of objects, 3, in a place that can be retrieved knowing only the pointer, nums. The compiler can use any technique it wants to use, but there are two popular ones.

The code generated by nums = new int[3] might store the number 3 in a static associative array, where the pointer nums is used as the lookup key and the number 3 is the associated value. The code generated by delete[] nums would look up the pointer in the associative array, would extract the associated size_t, then would remove the entry from the associative array.

The code generated by nums = new int[3] might allocate an extra sizeof(size_t) bytes of memory (possibly plus some alignment bytes) and put the value 3 just before the first int object. Then delete[] nums would find 3 by looking at the fixed offset before the first int object (that is, before *num) and would deallocate the memory starting at the beginning of the allocation (that is, the block of memory beginning the fixed offset before *nums).

Neither technique is perfect. Here are a few of the tradeoffs.

The associative array technique is slower but safer: if someone forgets the [] when deallocating an array of things, (a) the entry in the associative array would be a leak, and (b) only the first object in the array would be destructed. This may or may not be a serious problem, but at least it might not crash the application.

The overallocation technique is faster but more dangerous: if someone says delete nums where they should have said delete[] nums, the address that is passed to operator delete(void* nums) would not be a valid heap allocation—it would be at least sizeof(size_t) bytes after a valid heap allocation. This would probably corrupt the heap. - C++ FAQs

Prabhu Jayaraman