Reputation: 1480
In my endless pursuit of happiness I came across something like this
auto temp = new int;
delete[0] temp;
and in my mind I was like... "This can't be right !" so I fired up the most special and rebellious snowflake compiler to test it and, lo and behold, it compiled and ran without any issues !
I then tried it in GCC (4.8.1) and it rejected it with this error
error: expected ‘]’ before numeric constant
So I ask you my fellow comrades, which one is right? ( surely not MSVC(11) ?! ) and if you could quote the standard that would be great.
Upvotes: 3
Views: 184
Reputation: 2629
It ran without issues because you were lucky. Generally allocating with new and deleting with delete[] is Undefined Behaviour and "running without any issues" belongs to the set of behaviours allowed by UB. A code like this sometimes runs fine in tests but breaks at the most unexpected moment, e.g. live demo for your most important customer.
Upvotes: 0
Reputation: 490058
Back toward the dawn of C++, when you deleted an array you were required to specify the size of the array you'd allocated:
int * x = new int[10];
// ...
delete [10] x;
This led to many problems, so the requirement was eliminated long ago. By the time the first C++ standard was written, this syntax was no longer officially allowed.
Nonetheless, many compilers still accept this syntax for the sake of compatibility with older code that uses it. With MS VC++, this is accepted by default, but if you ask for standard compliance (-Za) you'll get an error like:
error C2203: delete operator cannot specify bounds for an array
Obligatory aside: you shouldn't be using new
to allocate an array anyway. Use std::vector
.
Upvotes: 12
Reputation: 8975
The standard knows of two different types of storage deallocation, single-object form storage deallocation, 18.6.1.1/10-19, which is
void operator delete(void * ptr) noexcept;
void operator delete(void * ptr, std::nothrow_t const &) noexcept;
and array form storage deallocation, 18.6.1.2/9-17, which is
void operator delete[](void * ptr) noexcept;
void operator delete[](void * ptr, std::nothrow_t const &) noexcept;
However, historically (pre-standard) there was a delete[N]
deallocator, that required you to deallocate as much as you had allocated for your array. I suspect that is what your compiler is interpreting.
Upvotes: 3
Reputation: 122383
delete[0]
is illegal syntax according to the current standard..
Plus, when you allocate an object with new
, you should deallocate it with delete
, and new []
with delete []
. They are not supposed to be interchangeable.
C++11 §5.3.5 Delete
The delete-expression operator destroys a most derived object (1.8) or array created by a new-expression.
delete-expression:
::opt delete cast-expression ::opt delete [ ] cast-expression
The first alternative is for non-array objects, and the second is for arrays. The operand shall have a pointer type, or a class type having a single conversion function (12.3.2) to a pointer type. The result has type
void
.
Upvotes: 5