Chris L
Chris L

Reputation: 1011

In C++, what happens when the delete operator is called?

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;

Upvotes: 2

Views: 2943

Answers (3)

josh
josh

Reputation: 14383

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

Upvotes: 0

Zan Lynx
Zan Lynx

Reputation: 54325

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.

Upvotes: 1

James McNellis
James McNellis

Reputation: 355039

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).

Upvotes: 19

Related Questions