سؤال

Assume I want to allocate only 256 bytes memory blocks

char * memory = new char[256];

than I use placement new to create a FooBar object (sizeof(Foobar)<=256)

FooBar * obj = new (memory) FooBar();

does

delete obj; //this also calls the destructor of FooBar

delete all the 256 bytes of memory?

Does the standard guarantee that the whole "memory" buffer is deallocated by just "deleting obj"? Or it is based on the type "FooBar" and therefore this operation has undefined behaviour?

Assumption: FooBar is the only object in the memory buffer.

This is not duplicate question, please first understand the question. It is not immediately evident what this code does.

هل كانت مفيدة؟

المحلول

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. [...]

  1. The pointer to your object was not created by the new expression but only object construction was done via placement new.
  2. The pointer at the address obj (which should, cast to void* be the same as memory cast to void* but afaik you can't even rely on that) points to was allocated using new[] so using delete[] 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.

نصائح أخرى

That is indeed undefined behaviour, the correct way of doing it is to call the destructor of every object allocated in that block of memory explicitly and then deallocate the memory block itself.

obj->~FooBar();
delete[] memory;

Remember that placement new just construct the object, it doesnt allocate the memory, so the object shouldnt free it. If YOU allocate the memory, you should free it, if you constructed the object, you should only deconstruct it.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top