Custom (pool) allocator with boost shared_ptr

myahya picture myahya · May 26, 2010 · Viewed 8.3k times · Source

I want objects managed by a shared_ptr to be allocated from a pool, say Boost's Pool interface, how can this be achieved?

Answer

utnapistim picture utnapistim · May 26, 2010

Here's the code to do what you want (probably won't compile as I don't have boost on hand and I'm writing it from memory):

class YourClass; // your data type, defined somewhere else

boost::object_pool<YourClass> allocator;

void destroy(YourClass* pointer)
{
    allocator.destroy(pointer);
}

boost::shared_ptr<YourClass> create()
{
    // usage of object_pool<??>::construct requires that you have a 
    // YourClass::YourClass(void) defined. If you need to pass arguments
    // to the new instance, you need to do that separately.
    // 
    // for example using a YourClass::Initialize(your,parameters,here) method
    // before returning from this function
    return boost::shared_ptr<YourClass>( allocator.construct(), &destroy );
}

// usage:
boost::shared_ptr<YourClass>  newObject = create();

I implemented this twice, in two different projects. In both, the create and destroy functions were synchronized (you can add a boost::mutex lock around the use of allocator) and they were members of a factory class (and the destroy's signature was modified to void (YourClass*) through the usage of boost::bind).

You can also avoid writing two extra functions (the destroy and create) by binding object_pool<YourClass>::destroy dirrectly in the boost::shared_ptr constructor.

I'm too lazy to write all that now :).

Edit (moved my answer comment in here for the code formatting):

To bind the destroy function:

class ClassFactory
{
    boost::object_pool<YourClass> allocator;
public:
    boost::shared_ptr<YourClass> create()
    {
        return boost::shared_ptr<YourClass>(
            allocator.construct(),
            boost::bind(&ClassFactory::destroy, this, _1) );
    }

    void destroy(YourClass* pointer)
    {
        allocator.destroy(pointer);
    }
};

ClassFactory should have a longer lifetime than the shared_ptr (if the ClassFactory instance is deleted, the this pointer passed to the shared_ptr instance will be invalid - and crash your app when the shared_ptr deletes the YourClass instance).