tags:

views:

265

answers:

4

Why is there a delete[]? From my understanding its to behave differently for arrays. However, why does it really exist? Theres only free in C and no free_array. Also in syntax the only difference between delete var and delete []var is the [] which has no params (i'm not telling the length of the array).

So why does delete[] really exist? I know someone will say you can overload delete and delete[] (at least i think that is possible) but lets say we are not overloading it. Why does it exist?

+2  A: 

If you delete an array, only first object's destructor will be called. delete[] calls destructors of all objects in array and frees array's memory.

alxx
+1: Beat me to it :-)
Jon Cage
If you `delete` something that was the result of `new xxx[N]`, you get _undefined behaviour_. Calling the destructor on only the first object is just one possible result.
Charles Bailey
+15  A: 

Typically, for non-POD classes, a delete[] expression must call destructors on a variable number of class instances that cannot be determined at compile time. The compiler typically has to implement some run time "magic" that can be used to determine the correct number of objects to destroy.

A delete expression doesn't have to worry about this, it simply has to destroy the one object that the supplied pointer is pointing to. Because of this, it can have a more efficient implementation.

By splitting up delete and delete[], delete can be implemented without the overhead needed to correctly implement delete[] as well.

Charles Bailey
+1: as always, in C++, you don't pay for what you don't need...
Matthieu M.
+3  A: 

Assume delete[] didn't exist, write the code for deleting the array vs deleting only the first element in the array.

delete array;        // Deletes first element, oops    
delete &array;       // Deletes first element, oops
delete &array[0];    // Deletes first element

A pointer to an array being an alias for a pointer to the first element of the array is of course an old C "feature".

Hans Passant
_@Hans_, this is perhaps a somewhat elliptical answer... but great as a demonstration why `delete[]` is needed. +1
stakx
@stakx: it doesn't demonstrate `delete[]` is *needed*, as such - the implementation could somehow flag whether an allocation is an array or not, just as it currently tracks the length of all allocations made with `new[]`. Then `delete` could check the flag and just do the right thing. Deleting the first element of an array is always wrong, so there's no need for a syntax to do it.
Steve Jessop
Erm, no, hard to implement vector::operator[] if there was no syntax for that.
Hans Passant
@Steve: that would require a runtime test, which C++ usually tries to avoid when possible.
Mike Seymour
@Mike Seymour: I thought about that too but chances are the length is hardcoded as a const so shouldnt passing in the const be best? I also thought a quick if statement to see if its an array or not would take very few cycles and space. Then i remember i havent implemented my own delete yet
acidzombie24
@Mike: true, but pretty much any memory allocator is going to involve a branch of some kind, somewhere. Avoiding this one is nice (as long as you don't mind occasional extra work, for example to write classes like `shared_array`), but not it's not as though C++ would be unworkable without that.
Steve Jessop
@Hans: I don't know what you mean. What does `vector::operator[]` have to do with deleting anything? My complaint is that you've said, "write the code for deleting an array vs. [something that's invalid]". Who cares what the code looks like to do something that's invalid? In our imagined version of C++, `delete array` would *mean*, "delete the whole array", and there would be no way to say, "delete the first element". `vector` uses an explicit call to the destructor to destroy elements, so that's unaffected.
Steve Jessop
@Steve: sorry, I had no idea that you were contemplating an imaginary version of the C++ language. My answer was based on the real one, the one that inherited the broken C arrays.
Hans Passant
_@Steve_, I also can't think of a reason why C++ should allow something which doesn't make sense, but it obviously does. That's why I sort-of like Hans' answer: There's probably no way to get it right with `delete` no matter what you try; thus you need something other than `delete`. (*tadaa!*, `delete[]` to the rescue, although he didn't say so in his original answer -- thus my comment about the answer being "somewhat elliptical".)
stakx
@Hans: when you said, "assume delete[] didn't exist", you embarked upon a consideration of an imaginary version of the C++ language, which I continued. If you're unwilling to consider hypotheticals, you probably shouldn't attempt a proof by contradiction ;-) Clearly if, as you hypotheise, `delete[]` didn't exist, then `delete` would be the way to delete arrays. It could quite easily be made to work, although as Mike says, the cost of my flag implementation would be a runtime check to distinguish arrays from "normal objects". Or objects could just be arrays of size 1, also costing a branch.
Steve Jessop
hahah. Hey guys Steve Jessop is completely right (everything on this page 100%). Also i marked Charles Bailey answer for a reason. My question was of the point that delete can delete the entire array if it is an array and not do the wrong thing (deleting or dtoring the first element only). Steves comment was actually what i was thinking every time. Anyways it looks like its an optimization thing and maybe a feature in case you want to overload array allocation/new only.
acidzombie24
@stakx: the reason C++ allows something that doesn't make sense is what Hans says. A pointer to the first element of an array isn't distinguished in the type system from a pointer to some single heap-allocated object, or from a pointer to the middle of an array. If you call `delete` to "free the first element of an array", instead of `delete[]` to free the whole array, the C++ language as it stands can't catch the error, so it's "allowed" only in the sense that you can write it but it's UB. A slightly modified C++ language, with some runtime costs, could catch it. So can a debugging allocator.
Steve Jessop
_@Steve_, I understood your point quite well, and my sentence was meant to agree with your opinion. The present argument as I see it is this: Hans showed that the present-day, real-world C++ without one feature (namely `delete[]`) would be missing something crucial, therefore that feature cannot be omitted. You, on the other hand, rightly state that if C++ did things a little smarter, `delete[]` wouldn't be necessary. You're both right, only perhaps you're considering C++ from a more "idealistic" point of view, while Hans' is the "realistic". I agree with you both.
stakx
@stakx: Actually i believe without delete[] one can write an implementation of delete without any loss excepting the ability to overload delete[] (because it doesnt exist anymore)
acidzombie24
+1  A: 

Consider:

int* a = new int[25];
int* b = a;

delete b;  // only deletes the first element

The C++ compiler has no idea whether b points to an array or a single element. Calling delete on an array will only delete the first element.

Alexander Rafferty
To be fair, you could say the same for `delete [] b`; how does it know that there are 25 items in the array? The answer is behind-the-scenes meta-information. In principle, the compiler could also store a boolean array/non-array flag in this meta-information. I think Charles' answer is the real reason.
Oli Charlesworth
The [] tells the compiler that there is meta information.
Alexander Rafferty
Even plain `delete` needs meta-information to be able to release the memory back to the heap, for example pointers to previous and next allocated blocks or something similar (heavily implementation dependent).
FredOverflow
The reason for `delete` and `delete[]` is so the compiler knows if you want to delete just that block or the whole array.
Alexander Rafferty