Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I delete other-than-first element from array by pointer

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?
like image 575
rsht Avatar asked Dec 25 '22 13:12

rsht


1 Answers

  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:

  • C++ FAQ: "What if I forget the [] when deleteing an array allocated via new T[n]?"
  • C++ FAQ: "After p = new Fred[n], how does the compiler know there are n objects to be destructed during delete[] p?"
like image 66
John Kugelman Avatar answered Feb 08 '23 22:02

John Kugelman