0

This question may sound a bit weird, but I never entirely got why do we need to have 2 different syntax for deleting dynamically allocated memory in C++?

For example,

int *p = new int[10];
delete[] p; // why not just delete p;?

In plain old C, you just use the free function to release the memory allocated for a pointer, regardless of the number of elements allocated. Of course, C++ is a bit more complicated, as it allows for class types, which invoke their destructor etc. However, I see no impediment in using a single syntax for deleting dynamically allocated memory in C++.

Is there any fundamental reason why it was decided to use 2 versions, delete and delete[]?

More than that, most compilers do not even warn you if you use delete instead of delete[], and this creates undefined behaviour.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • you are not deleting a pointer, you are using the `delete[]` operator on a pointer which is the wrong way to do this in the first place – user2485710 Nov 28 '14 at 23:30

3 Answers3

2

The underlying reason is that arrays don't have destructors. But arrays are still objects. Therefore, when arrays are allocated dynamically, they require special treatment. A pointer to an object is indistinguishable from a pointer to the first element of an array, so you need a special language construct to indicate that the pointer points into an array, and that multiple array elements need to have their destructors called.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • This makes sense, thanks for the answer, and it is what is happening now in C++ code. However, it shouldn't be impossible for a compiler to distinguish the cases, as I never see a mix between the 2. I.e., is there any reasonable example where you may want to use plain `delete` on a dynamically allocated array (of objects) in `C++`? If not, then it shouldn't be too hard for a compiler to keep track of what are arrays and what not, in a C++ source file. – vsoftco Nov 28 '14 at 23:37
  • @vsoftco: `void surprise_me(int * p) { delete p; }` – Kerrek SB Nov 28 '14 at 23:38
  • Fair enough, I'd wish I'd be able to give +n instead of +1 :) It's the old business of arrays decaying into pointers in function calls, which I personally hate (although I understand the feature for keeping backwards compatibility). – vsoftco Nov 28 '14 at 23:39
  • @vsoftco: I think that is misguided. The real problem is that dynamic arrays are very, very weird beasts. You can allocate an object of a dynamic type, namely a type which is *never* the type of an expression, by saying `new U[n]`, and you never get a pointer to the object. You only get a pointer to one of its subobjects. So array-to-pointer decay never plays a role since you never even see the array. – Kerrek SB Nov 28 '14 at 23:59
  • Ok, agree, but, same happens with `malloc` in a sense. You get a pointer to an `int`, however, when you call `free`, the compiler knows that you allocated e.g. 512 ints, and it releases them. My question was basically why cannot this be promoted to `C++`, with an extra call for the destructor of course. For the user point of view, the `int` pointer is no different as if would have been allocated for 1 `int`, or for `512` `int`s. – vsoftco Nov 29 '14 at 00:03
  • @vsoftco: `malloc` allocates memory, it does not create objects. Object lifetime does not begin (in general) until the first constructor has returned. This highlights again the problem with arrays: Arrays have no constructors, either. The lifetime of the array itself begins when its storage has been allocated, but the element subobjects may not be alive at this point. So arrays permit weird zombie states where the entire object is alive, but subobjects are not. That's highly unusual. – Kerrek SB Nov 29 '14 at 00:12
  • Kerrek, thanks much for your comments, have to think about them and try to understand what's going on. – vsoftco Nov 29 '14 at 00:13
  • @vsoftco: Sure, cheers. If the only thing you're taking away from today is that dynamically allocated arrays in C++ are really, really weird, then we've accomplished something :-) – Kerrek SB Nov 29 '14 at 00:14
  • Haha yeap, I totally agree with that :) – vsoftco Nov 29 '14 at 00:14
0

An expression with the delete[] operator, first calls the appropriate destructors for each element in the array (if these are of a class type), and then calls an array deallocation function.

From here

  • that I know, I didn't understand why cannot the compiler somehow just use `delete` instead of `delete[]` – vsoftco Nov 28 '14 at 23:33
0

The language allows you to overload the underlying allocation and deallocation functions. You might want to do this differently for single objects and for arrays; having two different operators allows you to do that.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644