Search code examples
c++memory-managementlanguage-lawyernew-operatordelete-operator

Why default operator delete[] can't deallocate the memory allocated by default operator new?


Due to unspecified overhead, it is illegal to deallocate with delete-expression that does not match the form of the new-expression.

However, default operator new and operator delete isn't the same.

operator new[]:

[new.delete#array-4]

Default behavior: Returns operator new(size), or operator new(size, alignment), respectively.

operator delete[]:

[new.delete#array-14]:

Default behavior: The functions that have a size parameter forward their other parameters to the corresponding function without a size parameter. The functions that do not have a size parameter forward their parameters to the corresponding operator delete (single-object) function.

It can be seen that default operator new[] and operator delete[] simply call operator new and operator delete.

However, operator delete[] can only deallocate the memory allocated by operator new[], according to [new.delete#array-9]:

Preconditions: ptr is a null pointer or its value represents the address of a block of memory allocated by an earlier call to a (possibly replaced) operator new or operator new[](std​::​size_­t, std​::​align_­val_­t) which has not been invalidated by an intervening call to operator delete[].

Therefore, the following code is illegal:

operator delete[](operator new(1));

Because void* operator new(std::size_t size) does not return void* operator new[](std::size_t size).

However, the following code is legal:

operator delete(operator new[](1));

According to [new.delete#single-10]:

Preconditions: ptr is a null pointer or its value represents the address of a block of memory allocated by an earlier call to a (possibly replaced) operator new(std​::​size_­t) or operator new(std​::​size_­t, std​::​align_­val_­t) which has not been invalidated by an intervening call to operator delete.

void* operator new[](std::size_t size) does return operator new(size), so no problem at all.

Is this asymmetric behavior an issue?


Solution

  • See LWG3789, the status of the issue has been set to NAD:

    "No reason to carve out an exception covering a case on something which can’t be observed by the program (whether the allocation operators are replaced). This just makes things more complicated for no good reason." "This would require changes to sanitizers and other dynamic analyzers, for zero practical benefit (except allowing bad code to go un-diagnosed)."