Consider:
delete new std :: string [2];
delete [] new std :: string;
Everyone knows the first is an error. If the second wasn't an error, we wouldn't need two distinct operators.
Now consider:
std :: unique_ptr <int> x (new int [2]);
std :: unique_ptr <int> y (new int);
Does x
know to use delete[]
as opposed to delete
?
Background: this question floated through my head when I thought array type qualification of pointers would be a handy language feature.
int *[] foo = new int [2]; // OK
int * bar = new int; // OK
delete [] foo; // OK
delete bar; // OK
foo = new int; // Compile error
bar = new int[2]; // Compile error
delete foo; // Compile error
delete [] bar; // Compile error
Unfortunately, they don't know what delete to use therefore they use delete
. That's why for each smart pointer we have a smart array counterpart.
std::shared_ptr uses delete
std::shared_array uses delete[]
So, your line
std :: unique_ptr <int> x (new int [2]);
actually causes undefined behavior.
Incidentally, if you write
std :: unique_ptr<int[]> p(new int[2]);
^^
then delete[]
will be used since you've explicitly requested that. However, the following line will still be UB.
std :: unique_ptr<int[]> p(new int);
The reason that they can't choose between delete
and delete[]
is that new int
and new int[2]
are exactly of the same type - int*
.
Here's a related question of using correct deleters in case of smart_ptr<void>
and smart_ptr<Base>
when Base
has no virtual destructor.