The C++ standard tells you why it is undefined what you're doing.
It may be the case that the deallocation that is invoked by delete
uses the prepended size info of the allocated block and deallocates it properly but you can't rely on that.
§5.3.5 Delete
The delete-expression operator destroys a most derived object (1.8) or array created by a new-expression. delete-expression:
- ::delete cast-expression
- ::delete [ ] cast-expression
The first alternative is for non-array objects, and the second is for arrays. Whenever the delete keyword is immediately followed by empty square brackets, it shall be interpreted as the second alternative. [...]
That to be said, now we come to the more interesting part:
2 [...] In the first alternative (delete object), the value of the operand of delete may be a null pointer value, 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. [...]
- The pointer to your object was not created by the new expression but only object construction was done via placement new.
- The pointer at the address
obj
(which should, cast tovoid*
be the same asmemory
cast tovoid*
but afaik you can't even rely on that) points to was allocated usingnew[]
so usingdelete[]
is mandatory.
See those related questions:
If you want to have a pre-allocated storage for several objects of the same type:
consider using std::vector<FooBar>::reserve()
.
emplace_back()
or push_back()
will then do in-place construction of the objects.