I'm trying to use a boost::pool_allocator to (efficiently) allocate std::shared_ptr<T>. Conceptually, I want something like this:
struct Foo {};
std::shared_ptr<Foo> create() {
static boost::pool_alloator<Foo> alloc;
return std::allocate_shared<Foo>(alloc);
}
There is one problem with this example: boost::pool_allocator<Foo> is optimized for allocations of size sizeof(Foo) (in fact I'm surprised that it supports allocations of different sizes at all…). But std::allocate_shared<Foo>(…) does not allocate sizeof(Foo) bytes, because it allocates the control block and the payload in one go.
To efficiently use boost::pool_allocator<…> with std::allocate_shared, I would need to inform the pool_allocator about the size of the allocations to expect. To do that, I would probably need the type that allocate_shared allocates internally. I'm pretty sure that for GCC's STL implementation, that type would be _Sp_counted_ptr_inplace, and for Clang's libc++ it looks like it's __shared_ptr_emplace::_Storage - but using these types would obviously not be portable.
Is there any standard-compliant way of figuring out the size of the allocations that std::allocate_shared will perform? Or any other way to (efficiently) use a pool allocator for allocate_shared?
The allocator is rebound to the internal type of whatever it is allocating, and a copy of the allocator with the appropriate type is used instead.
pool_allocator<Foo> is a bit misleading since it is rebound to the larger type. Usually, you use allocator<void> when you know it will be rebound:
std::shared_ptr<Foo> create() {
static boost::pool_allocator<void> alloc;
return std::allocate_shared<Foo>(alloc);
}
This way you know for sure no extra work is done to handle allocators for a smaller sized object that's never actually used
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With