C++ placement new and delete
I was trying to write some debug memory allocation routines the other day and I decided I would attempt to use placement new. I hunted down some useful references:
If you are not familiar with the syntax it goes like this:
extern void* ::operator new(size_t size, char* pLine, int line);
...
char* p = ::new(__FILE__, __LINE__) char[100];
The first line shows how to declare an override of the new operator with two placement arguments, in this case a char* and int which would allow you to record the location of the allocation.
The logical extension to this mechanism is to actually create a placement override that passes a function pointer or a class instance to use for the memory allocation, like this:
extern void* ::operator new(size_t size, Allocator* pAllocator);
...
char* p = ::new(pAllocator) char[100];
Seems all well and good, but how do we delete memory allocated using placement new? There must be a placement delete, right? Well, there is but as with most things in the committee designed C++ language it doesn't work the way you might expect.
You can indeed declare a placement delete operator overload:
extern void ::operator delete(void* p, Allocator* pAllocator);
...
::delete(pAllocator) p; // This doesn't compile!
p->~ClassName(); pAllocator->Delete(p);
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
The ::delete line doesn't compile. The fact is, you can't explicitly call placement delete, making it effectively useless in my opinion for many uses. You must explicitly call any class destructor and your allocator's Delete or Free method.
So why use is it to create placement new override? Well, it turns out that if you classes constructor throws an exception then the appropriate placement delete override will get called. How nutty is that! The compiler knows enough to use the placement delete properly, but there's not C++ syntax to expose it for general use!
The need to explicitly call destructors and clean-up memory is particularly annoying when allocating arrays of objects. You must loop through all your objects calling destructors, etc.. Good luck creating a macro or a template to simplify things.
In my opinion, creating placement delete syntax is entirely feasible for compiler writers. The compiler knows all about the types of the classes involved, whether they are arrays, etc.. Hopefully this idea will work it's way through a future C++ committee meeting.