user1432882
user1432882

Reputation: 1152

How to set allocator for dynamically allocated stl container?

I am using TBB custom memory allocator.

tbb::memory_pool<std::allocator<char>> shortTermPool;
typedef tbb::memory_pool_allocator<Result*> custom_allocator;
std::vector<Result*,custom_allocator>* results =(std::vector<Result*,custom_allocator>*)shortTermPool.malloc(sizeof(std::vector<Result*,custom_allocator>));

The issue is that setting the allocator is in the constructor. Malloc doesn't call the constructor. The default usage would be something like this:

tbb::memory_pool<std::allocator<char>> shortTermPool;
typedef tbb::memory_pool_allocator<Result*> custom_allocator;
std::vector<Result*,custom_allocator> results (custom_allocator(shortTermPool));

Is there a way to do a malloc of the stl container, and then afterward assign a custom allocator?

Upvotes: 4

Views: 781

Answers (1)

WhiZTiM
WhiZTiM

Reputation: 21576

After doing this:

std::vector<Result*,custom_allocator>* results = (std::vector<Result*,custom_allocator>*)shortTermPool.malloc(sizeof(std::vector<Result*,custom_allocator>));

You will need to use placement-new to construct the object:

new(results) std::vector<Result*,custom_allocator>(custom_allocator(shortTermPool));

Though, doing something like this below is perhaps more readable:

using MemoryPool = tbb::memory_pool<std::allocator<char>>;
using CustomAllocator = tbb::memory_pool_allocator<Result*>;
using CustomVector = std::vector<Result*, CustomAllocator>;

MemoryPool shortTermPool;
void* allocatedMemory = shortTermPool.malloc(sizeof(CustomVector);
CustomVector* results = static_cast<CustomVector*>(allocatedMemory);
new(results) CustomVector(CustomAllocator(shortTemPool));

EDIT

Remember not to use delete on the pointer since the memory it points to wasn't allocated by new; and remember to explicitly destruct the object like this:

results->~CustomVector();

More completely:

MemoryPool shortTermPool;
void* allocatedMemory = shortTermPool.malloc(sizeof(CustomVector);
CustomVector* results = static_cast<CustomVector*>(allocatedMemory);
new(results) CustomVector(CustomAllocator(shortTemPool));

/* Knock yourself out with the objects */

/*NOTE: If an exception is thrown before the code below is executed, you'll have a leak! */

results->~CustomVector();
shorTermPool.free(results);

//Don't do
//delete results

You may also want explore the use of smart pointers with custom deleters to handle the proper destruction and freeing of memory gotten from tbb's memory allocators

Upvotes: 6

Related Questions