Search code examples
c++boostshared-ptrallocator

Why does boost::allocate_shared<T> (alloc) ignore alloc.construct() and does std::allocate_shared<T> (alloc) behave alike?


I want to write a custom allocator which invokes a createHook() just after object construction and a symmetrical destroyHook() just before object destruction. I am using my allocator this way:

class Object {};
class CustomAllocator { /* ... */ };

boost::shared_ptr<Object> object = boost::allocate_shared<Object> (CustomAllocator ());

While allocate_shared<> correctly calls allocate() on my allocator, it does use an in-place new statement rather than calling construct() on my allocator.

I know how to circumvent this problem in general by writing a custom my_allocate_shared() version which invokes the createHook() and returns a shared_ptr<> instance with a custom deleter (which in turn invokes the destroyHook()), but i am loosing the allocate_shared<> optimization then.

My coding environment is restricted to C++03, so i don't know how std::allocate_shared() in a C++11 context behaves (or should behave).


Solution

  • As far as std::allocate_shared is concerned, the behaviour you're seeing is correct. Quoting C++11 [util.smartptr.shared.create]:

    template<class T, class... Args> shared_ptr<T> make_shared(Args&&... args);
    template<class T, class A, class... Args>
    shared_ptr<T> allocate_shared(const A& a, Args&&... args);
    

    2 Effects: Allocates memory suitable for an object of type T and constructs an object in that memory via the placement new expression ::new (pv) T(std::forward<Args>(args)...). The template allocate_shared uses a copy of a to allocate memory. If an exception is thrown, the functions have no effect.

    Since the standard library shared pointer support is largely based on the Boost implementations, I would say it makes sense that Boost behaves likewise.

    As @KerrekSB pointed out in comments, there is apparently a standard library active issue 2070 about this.