The better and saner way, as explained in other answers, is
buf->~Buffer();
::operator delete(mem);
However, assuming there's no such thing as Buffer::operator delete
, the delete buf;
version is technically okay and will do all the same cleanup. To avoid the Buffer::operator delete
possibility, you can say ::delete buf;
.
Language-lawyer debate material follows.
5.3.5/1
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. ...
5.3.5/2
... In the first alternative (delete object), the value of the operand of delete
may be a null pointer, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject (1.8) representing a base class of such an object (Clause 10). If not, the behavior is undefined.
So the pointer must point at an object created by a new-expression, which is defined:
5.3.4/1
new-expression:
::
opt new
new-placementopt new-type-id new-initializeropt
::
opt new
new-placementopt (
type-id )
new-initializeropt
new-placement:
So a "placement new" does count as a new-expression. Nothing forbidding a delete-expression there.
Also, it turns out the delete-expression does exactly the right things to clean up the object despite the custom creation.
5.3.5/6-9
If the value of the operand of the delete-expression is not a null pointer value, the delete-expression will invoke the destructor (if any) for the object or the elements of the array being deleted. ...
If the value of the operand of the delete-expression is not a null pointer value, the delete-expression will call a deallocation function (3.7.4.2). Otherwise, it is unspecified whether the deallocation function will be called. [Note: The deallocation function is called regardless of whether the destructor for the object or some element of the array throws an exception. - end note]
When the keyword delete
in a delete-expression is preceded by the unary ::
operator, the global deallocation function is used to deallocate the storage.
So ::delete buf;
is entirely equivalent to:
try {
buf->~Buffer();
} catch(...) {
::operator delete(mem);
throw;
}
::operator delete(mem);
operator new
andoperator delete
inside ofBuffer
to allocate extra space, then to write something likenew (strlen(charString) + 1) Buffer;
– Cavalcade