Method said:
I understand that "delete xp" deletes a scalar object and "delete [] xp"
deletes an array of objects, but what I don't understand is why you need
to tell the compiler which you're doing.
When you do "delete [] xp", the delete procedure (not sure if that's the
right terminology) obviously knows how many objects were allocated by
the corresponding "new" call. So, why can't it just know whether you
did "new x" or "new x[n]"?
Existence of 'delete' along with 'delete[]' allows some deallocation
code to be optimised a bit better. For example, if you are sure that
there is only one object to be destroyed, there is no need to look up
the size of the "array", so 'delete' is a bit more efficient than its
"array" counterpart.
I can't imagine much of an optimization advantage by using "delete []". How
much does one table lookup really cost for the array size? And if "delete
[]" was that much more efficient, why didn't they add a "free []" (along
with "malloc[]") feature as well?
I guess they chose to have "delete[]" to make it a compliment in syntax to
"new x[n]".
new X[N] is the equivalent of
// warning - this code is not tested or checked and guarenteed broken
template <typename X>
X * MyNew( unsigned N )
{
// need to guarentee alignment - so statement below might be broken
void * t = malloc( sizeof( int ) + sizeof( X ) * N );
if ( ! t )
{
throw bad_alloc();
}
X * ptr = sizeof( int ) + (char *) t;
for ( int i = 0; i < N; ++ i )
{
// perform construction
new ( ptr + i ) X();
// oops need to handle exception --- broken again
}
* ( int * ) t = N;
return ptr;
}
delete[] is equivalent to
template <typename X>
void MyDelete( X * ptr )
{
if ( ! ptr ) return;
void * t = ( void * )( (char *) ptr ) - sizeof( int ) );
int N = * ( int * ) t;
for ( int i = N; i --; )
{
// call destructor
( ptr + i )->~X();
// oops need to handle exception --- baroke
}
free( t );
return ptr;
}
The point is, comparing delete[] and free() makes little sense.