4

Consider following code:

int main()
{
  int *intArPtr = new int[100];
  int *intArPtr1 = intArPtr + 1;

  delete [] intArPtr; //ok
  //delete intArPtr; //valgrind warning, but no leaks!
  //delete intArPtr1; //invalid pointer error

  return 0;
}

I know that delete [] intArPtr is the only valid way to delete this array, but I'm just curious about following:

  1. Why delete intArPtr doesn't yield any memory leaks? Is it undefined behavior and I'm just lucky not to have any?
  2. Why delete intArPtr1 gives an error on run-time? Why doesn't it delete all elements but first from the array?
  3. How does C++'s runtime knows size of the allocated array (for delete [])? Is it stored somewhere?
rsht
  • 1,522
  • 12
  • 27

3 Answers3

12
  1. Why delete intArPtr doesn't yield any memory leaks? Is it undefined behavior and I'm just lucky no to have any?

Correct, it is undefined behavior to call delete on memory allocated with new[]. For one, it won't call the destructors on the array members.

For two, even if you are just asking about memory deallocation and not about object destruction, it's possible for delete and delete[] to be implemented identically, or for them to be different. They read like they're the same thing but they're not: delete and delete[] are two different operators with potentially different implementations. They could use different allocation strategies (see the answer to question #3 below).

  1. Why delete intArPtr1 gives an error on run-time? Why doesn't it delete all elements but first from the array?

You have to pass delete a pointer allocated with new. The exact pointer. Not a pointer within a new-allocated memory region, that doesn't work. It has to be the same pointer to the start of the region.

  1. How does C++'s runtime knows size of the allocated array (for delete [])? Is it stored somewhere?

A common allocator strategy is to store the number of bytes allocated right before the allocated region. delete would then take the pointer you pass it, look 4 or 8 bytes to the left, and interpret that integer as the size of the region. If you pass it a pointer to somewhere else its lookback strategy will fail.

The C++ language doesn't specify how memory allocation is tracked, so this is an implementation detail. Different standard libraries, compilers, and operating systems will do this differently. What I described is just one possible mechanism.

Further reading:

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • That clarify a lot for me. Thanks! – rsht Sep 30 '15 at 21:42
  • `delete` and `delete[]` cannot possibly be "implemented identically". For POD types, the effects of calling either may be indistinguishable, but for user-defined types that contain pointers to other allocations owned by the objects being deleted, there is a profound difference between calling `delete` and calling `delete[]`, even on systems where the effects of using them incorrectly on POD types is indistinguishable. The key issue is that `delete` will call the type's destructor only once, for the object at [0], while `delete[]` will call the destructor for each object in the array. – phonetagger Sep 30 '15 at 22:03
  • @phonetagger: It certainly is possible for `delete` and `delete[]` to be implemented identically, if, for example, `new T` was implemented to have the same effect as `new T[1]`. – Benjamin Lindley Sep 30 '15 at 22:27
0
  1. Why delete intArPtr doesn't yield any memory leaks? Is it undefined behavior and I'm just lucky no to have any?

Yes and no at the same time. Using delete instead of delete[] is not clean, but usually works. Basically the pointer and offset are both stored at allocation time. This allows a proper deallocation to occur when using delete, even by accident.

  1. Why delete intArPtr1 gives an error on run-time? Why doesn't it delete all elements but first from the array?

intArPtr1 does not correspond to the pointer of the allocated area. When trying to delete that, the runtime cannot find this address in the allocation table.

  1. How does C++'s runtime knows size of the allocated array (for delete [])? Is it stored somewhere?

It is stored in the allocation table, with the pointer to the allocated area.

Shlublu
  • 10,917
  • 4
  • 51
  • 70
-2

Answers:

  1. No memory leaks in your exampe. As a matter of fact, deleting array without [] will only cause memory leaks if the objects inside arrays have some memory allocated themselves and are supposed to free that memory in the destructor. In all other cases, improper delete will not cause a memory leak.
  2. Because the size of memory allocated is stored just before the pointer. When you are accessing any other element of the array but the first, there is no proper memory size there.
  3. See 2.
SergeyA
  • 61,605
  • 5
  • 78
  • 137