Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Global "placement" delete[]

Tags:

c++

visual-c++

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.

like image 786
Gwaredd Avatar asked Nov 27 '09 16:11

Gwaredd


People also ask

When to use delete [] and delete?

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.

How do you delete a placement call?

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.

What is deallocation in C++?

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.

Why we use new and delete in C++?

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).


1 Answers

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.

like image 198
chollida Avatar answered Sep 25 '22 09:09

chollida