# Smart pointer memory pool

I'm using a third-party library which utilizes boost::shared_ptr for memory management.

The problem is that I need to allocate many objects and I have detected that the allocation and deallocation is rather resource-demanding. So I thought I should utilize a smart-pointer memory pool to reduce the overhead.

#include <boost/smart_ptr/make_shared_array.hpp>

template <class T, size_t pool_size>
class shared_ptr_pool
{
boost::shared_ptr<T[]> pool;
size_t avail = 0;

public:
boost::shared_ptr<T> make_shared()
{
if (!avail)
{
pool = boost::make_shared<T[]>(pool_size);
avail = pool_size;
}

return boost::shared_ptr<T>(pool, &pool[--avail]);
}
};


The solution is to utilize make_shared for arrays and the shared_ptr aliasing constructor. The solution in inherently thread-unsafe, but for my needs that is okay.

Any thoughts, comments or pretty much anything would be appreciated.

• The main advantage of a pool is that released pointers can quickly be re-used. I don't see that functionality here. Once your pool is empty you need to re-create another pool. – Martin York Mar 24 '14 at 1:07
• This might be a silly question. But why would you use a third party library for something that is already in the language? – Mads Mar 25 '14 at 1:26
• @Mads: The third-party library I use in turn use boost::shared_ptr because of performance, portability and it correctly uses delete[] on array types. – dalle Mar 25 '14 at 8:44
• @LokiAstari: You are correct, this isn't a pool as such, as it doesn't return objects to the pool, but a chunk-allocator-thingy (?). – dalle Mar 25 '14 at 8:46

Per the comments, this isn't really a "pool" because things don't go back into it when you're done using them. It's just an "incremental allocator" that does allocation in "chunks". A better name for it might be shared_ptr_chunk_allocator (and chunk_size instead of pool_size).

Given that pool_size is used only on the codepath that also allocates memory (so it's not a super speed-critical path where one more memory load would hurt performance), and shared_ptr_pool<...> has non-static data members (so there's no harm in adding one more non-static data member), surely it would make more sense to make pool_size a runtime parameter to shared_ptr_pool's constructor.

// your current code:
shared_ptr_pool<myclass, 16> pool;
// versus my suggestion:
shared_ptr_pool<myclass> pool(16);


This would even allow you to provide a member function for modifying the chunk size on the fly, in case maybe your code could detect that its particular workload demanded a bigger chunk size.

if (memory_usage_low && still_spending_lots_of_time_in_allocation) {
pool.set_chunk_size(pool.chunk_size() * 2);
}


The actual code implementation looks fine to me; nothing to complain about there. :)

You might be pleased to (or, you might already) know that std::shared_ptr<T[]> is part of the Library Fundamentals v1 Technical Specification, which I think means it ought to be coming to C++1z. However, it's not in the working draft yet as of N4567 (November 2015).