I have a type with the following structure:
class Block
{
/* few fixed size fields*/
...
/* fixed size byte array*/
std::unique_ptr<std::uint8_t[]> data;
}
These objects are used in a work pipeline and there are gonna be a lot of such objects. Size of data
is a runtime parameter, but it's known before work starts and it doesn't change later.
I want to use a memory pool (boost::pool/boost::object_pool in particular) to preallocate a lot of such objects with the such layout that each Block
object is followed by it's data
array.
How can I achieve this?
I think your only option is to write a custom allocator on top of your boost::pool and use it to get pointers to the memory. You can have a first start by looking at How to use boost::pool library to create a custom memory allocator for writing such an allocator.
Basically this custom allocator will allocate a large array of memory (at least one) and give back pointers to blocks and data with boost::pool. Modify the first answer of the previous post so that it doesn't rely on the size of T, but on a custom size passed as a paremeter. This size should be sizeof(Block) + data_length
.
Now, what you could do is cheat and change your class:
class Block
{
uint8_t* data;
};
Now when you ask for a new Block
, you don't get just your Block
, you also get the data block afterwards. When you construct your object (placement new), pass also the pointer to the new data (that would be the return of the allocator + sizeof(Block)
.
When the data is freed, don't forget to first call the destructor as this is required for placement new.
Of course, there are still lots of small details that you will have to solve, but this should give you a start.