Narek
Narek

Reputation: 39881

Can I call delete on the pointer which is allocated with the placement new?

Can we call delete on the pointer which is allocated with the placement new? If no then why? Please explain in details.

I know that there is no placement delete. But I wonder why just delete opetator can not delete the memory without caring how that memory on which the pointer points is allocated?

delete is doing two things:

  1. Calls destrucor
  2. Frees memory

And I see no reaason for delete not to be able to call either of these two operations on the object which was created by placement new. Any idea about reasons?

Upvotes: 5

Views: 1630

Answers (5)

Seth Carnegie
Seth Carnegie

Reputation: 75150

You must only call delete on pointers that were created with operator new. If you use placement new with a memory location that was allocated by the normal operator new then you may safely use delete on it (provided you get the types and pointers right). However, you can use placement new on any memory, so you usually will manage that memory some other way and call the object's destructor manually.

For instance, in this convoluted and usually unnecessary scenario, it is safe to delete the memory you used placement new on, but only because you allocated it with new before:

char* mem = new char[sizeof(MyObject)];
MyObject* o = new (mem) MyObject;

// use o

o->~MyObject(); // with placement new you have to call the destructor by yourself

delete[] mem;

However, this is illegal:

char mem[16]; // create a buffer on the stack, assume sizeof(MyObject) == 16

MyObject* o = new (mem) MyObject; // use stack memory to hold a MyObject
                                  // note that after placement new is done, o == mem
                                  // pretend for this example that the point brought up by Martin in the comments didn't matter

delete o; // you just deleted memory in the stack! This is very bad

Another way to think of it is that delete only deallocates memory allocated previously by the normal new. With placement new, you do not have to use memory that was allocated by the normal new, so with the possibility of not having been allocated by normal new, delete cannot deal with it.

Upvotes: 8

Remus Rusanu
Remus Rusanu

Reputation: 294407

EDIT1: I know that there is no placement delete. But I wonder why just delete opetator can not delete the memory without caring how that memory on which the pointer points is allocated?

Because each flavour of memory allocation uses some implementation specific tracking of the memory (usually a header block that precedes the user address) and this make the allocation/deallocation to work only when paired up correctly:

  • new must pair with delete
  • new[] must pair with delete[] (most implementations though forgive mixing the newand new[])
  • malloc and frieds must pair with free
  • CoTaskMemAlloc pairs with CoTaskMemFree
  • alloca pairs with nothing (stack unwinding takes care of it)
  • MyCustomAllocator pairs with MyCustomFree

Attempting to call the wrong deallocator will result in unpredictable behavior( most likely seg fault now or later). Therefore calling delete on memory allocated by anything else other than new will result in bad things.

Furthermore the placement new may be called on any address, may not even be an allocated address. It can be called on an address located in the middle of some larger object, it may be called on a memory mapped region, it may be called on a raw virtual committed region, anything goes. delete woul attempt, in all these cases, to do what its implementation tell him to do: subtract the header size, interpret it as a new header, link it back into the heap. Kaboom.

The one that know how to release the memory of a placement new address is you, since you know exactly how was that memory allocated. delete will only do what it knows, and it may not be the right thing.

Upvotes: 6

Christian Rau
Christian Rau

Reputation: 45948

No, because a placement new doesn't allocate any memory. You use placement new on previously allocated raw memory. The only thing it does is call the constructor of the object.

Upvotes: 1

Antti
Antti

Reputation: 12489

No, since delete not only calls the destructor but also frees the memory, but if you used placement new you must have allocated the memory yourself using malloc() or stack. You do, however, have to call the destructor yourself. Also see the C++ FAQ.

Upvotes: 5

Kerrek SB
Kerrek SB

Reputation: 477408

No. There is no placement-delete expression.

Typical scenario:

void * const addr = ::operator new(sizeof(T));  // get some memory

try {
  T * const pT = new (addr) T(args...);    // construct
  /* ... */
  p->~T();                                      // nap time
}
catch (...) {
}
::operator delete(addr);  // deallocate
                          // this is _operator_-delete, not a delete _expression_

Note that the placement-new operator does have a corresponding delete operator which is mandated to be precisely void ::operator delete(void* [, size_t]) { }, a no-op; this is what gets called if the constructor of T throws an exception.

Upvotes: 0

Related Questions