Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2003-10-13 12:46:17


Dave Harris wrote:
> In-Reply-To: <bmdir4$dn3$1_at_[hidden]>
> ghost_at_[hidden] (Vladimir Prus) wrote (abridged):
>> Can I shamelessy take a free C++ lesson? ;-)
>
> I'm not the best person to give it to you. The problem was raised by
> David Abrahams, and I see he has now posted a draft of a solution. To
> be honest I am struggling to keep up with him :-)
>
>
>> 2. Is the issue that if object is created in raw memory via placement
>> new, then if it's deleted by a program, the raw memory is never
>> freed?
>
> It'll be freed, but in the wrong way.
>
> char *buf = operator new( sizeof(T) ); // Global new.
> T *pt = new(buf) T;
> // ...
> delete pt; // Class-specific delete.
>
> If the class has overloaded non-placement operators, we will be
> calling
> the class version of operator delete() but not the class version of
> operator new(). This mismatch will lead to tears.
>
> We can't control destruction here, so we need to call the class
> version of operator new() as well - but there may not be one.

You can derive from T and invoke operator new from class scope:

#include <cstddef>
#include <iostream>
#include <new>

template<class T> struct helper: public T
{
    static void * alloc()
    {
        return operator new(sizeof(T));
    }
};

struct Y
{
    void * operator new(std::size_t n)
    {
        std::cout << "Y::operator new(" << n << ")\n";
        return ::operator new(n);
    }

    void operator delete(void * p, std::size_t n)
    {
        std::cout << "Y::operator delete(" << p << ", " << n << ")\n";
        return ::operator delete(p);
    }
};

int main()
{
    void * p = helper<Y>::alloc();
    ::new(p) Y();
    delete (Y*)p;
}

Note the :: before the palcement new. Required if the class doesn't have a
class-specific placement new defined, as in the example.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk