I wonder if this code is legal:
delete new (operator new(1)) char;
This code does the same thing, but doesn't use delete expression on a pointer obtained from placement new:
void* p = operator new(1);
new (p) char;
delete static_cast<char*>(p);
The standard rules at [expr.delete#2]:
In a single-object delete expression, the value of the operand of delete may be a null pointer value, a pointer value that resulted from a previous non-array new-expression, or a pointer to a base class subobject of an object created by such a new-expression. If not, the behavior is undefined. In an array delete expression, the value of the operand of delete may be a null pointer value or a pointer value that resulted from a previous array new-expression.68 If not, the behavior is undefined.
The standard does not say that new-expression does not include placement new. So I think according to the standard, the first piece of code should be legal, but the second should be illegal. Is my idea correct?
Why the standard says that? Calling operator new and constructing an object on it does almost the same thing as the new expression, but using the delete expression on the obtained pointer is not necessarily legal.
For allocating an array, the standard seems to allow this:
delete[] new (operator new[](2)) char[2];
But it should be illegal due to unspecified overhead.
Why does the standard allow that?
EDIT: According to [intro.object]/13:
Any implicit or explicit invocation of a function named operator new or operator new[] implicitly creates objects in the returned region of storage and returns a pointer to a suitable created object.
So I can even write the following code:
delete static_cast<char*>(operator new(1));
It destroys the implicitly created char
object and deallocates the memory, doing the same thing as the examples above. But it's definitely illegal according to the standard because no new-expression is used.
Why doesn't the standard allow that?
delete[] new (operator new(2)) char[2];
isn't legit. Can'tdelete[]
something that was notnew[]
(asoperator new(2)
isn'tnew[]
). And the mismatched type for new/delete can't be good either. – Baaldelete[]
must correspond tonew[]
. – Fowling[expr.delete#2]
citation. – Baaldelete[]
must correspond tonew[]
. – Baalnew[]
– Fowlingstd::unique_ptr
or for arraysstd::vector
and for stringsstd::string
. – Dictum