I am trying to replace new/delete with my own allocator(s). So, overriding placement new and delete - quite happy with that. Looks something like this ...
void* operator new( size_t size, Allocator* a )
{
return a->Alloc( size );
}
template<class T> inline void MyDelete( T* p, Allocator* a )
{
if( p )
{
p->~T();
a->Free( p );
}
}
The C++ language specifies that, for placement delete, you have to explicitly call the ~dtor. The compiler doesn't do it for you. Whether this is a templatised operator delete or explicit function as shown.
See http://www2.research.att.com/~bs/bs_faq2.html#placement-delete
The problem is - how can I get this to work for array delete[]? I know I need to iterate through the array and call ~dtor myself. Therefore I need the size of the array,
Edited for clarity
I can store this information or infer it from the block size. However, the problem is the compiler (MSVC v9) does different things if I am allocating an array of objects with destructors compared to ones without, i.e. if there is a dtor it will allocate an extra 4 bytes. This is because the compiler for standard delete[] needs to do the same thing and can pair up the appropriate code for delete[].
However in my own "placement" delete[] I have no way of knowing what the compiler did or determining safely at compile time if the class has a dtor.
E.g.
char buf[ 1000 ];
MyClass* pA = new( buf ) MyClass[ 5 ];
Here the value of pA is buf + 4 if there exists ~MyClass() and the amount of memory allocated is sizeof(MyClass) * 5 + 4. However if there is no dtor then pA == buf and the amount of memory allocated is sizeof(MyClass) * 5.
So my question is - is this behaviour a language standard and consistent across compilers or is it a peculiar to MSVC? Has anyone else got a good solution to this problem? I guess the only option is to not use new[] and do the construction myself which is fine but then the calling code syntax is a little unusual .. or force every class to have a destructor.
delete is used for one single pointer and delete[] is used for deleting an array through a pointer. This might help you to understand better.
Placement deleteIt is not possible to call any placement operator delete function using a delete expression. The placement delete functions are called from placement new expressions. In particular, they are called if the constructor of the object throws an exception.
std::allocator::deallocate void deallocate (pointer p, size_type n); Release block of storage. Releases a block of storage previously allocated with member allocate and not yet released. The elements in the array are not destroyed by a call to this member function.
C++ supports dynamic allocation and deallocation of objects using the new and delete operators. These operators allocate memory for objects from a pool called the free store (also known as the heap).
When in doubt go to the expert:
http://www.stroustrup.com/bs_faq2.html#placement-delete
But how can we later delete those objects correctly? The reason that there is no built-in "placement delete" to match placement new is that there is no general way of assuring that it would be used correctly. Nothing in the C++ type system allows us to deduce that p1 points to an object allocated in Arena a1. A pointer to any X allocated anywhere can be assigned to p1.
The rest of the link goes onto describe how to remedy the situation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With