I would like to take advantage of the following advertised feature of boost::fast_pool_allocator
(see the Boost documentation for Boost Pool):
For example, you could have a situation where you want to allocate a bunch of small objects at one point, and then reach a point in your program where none of them are needed any more. Using pool interfaces, you can choose to run their destructors or just drop them off into oblivion...
(See here for this quote.)
The key phrase is drop them off into oblivion. I do not want the destructors called on these objects.
(The reason is that I have millions of tiny objects that form an extremely complex web of ownership on the heap, and it takes my program about 20 minutes to call all of the destructors when the single parent-most object goes off the stack. I do not need these destructors called, because there are no desired side effects and all memory is contained within the boost::pool
.)
Unfortunately, despite the promise of the above documentation, and the promise of the boost::pool
concept, I cannot find a way to prevent the destructors of the managed objects from being called.
The problem is easily isolated in a small sample program:
class Obj
{
public:
~Obj()
{
// Placing a breakpoint here indicates that this is *always* reached
// (except for the crash scenario discussed below)
int m = 0;
}
};
typedef std::map<int, Obj, std::less<int>,
boost::fast_pool_allocator<std::pair<int const, Obj>>>
fast_int_to_int_map;
class Foo
{
public:
~Foo()
{
// When the following line is uncommented, the program CRASHES
// when the destructor is exited - because the Obj destructors
// are called on the invalid Obj ghost instances
//boost::singleton_pool<boost::fast_pool_allocator_tag,
// sizeof(std::pair<int const, Obj>)>::purge_memory();
}
fast_int_to_int_map mmap;
};
void mfoo()
{
// When this function exits, the Foo instance goes off the stack
// and its destructor is called, in turn calling the destructors
// of the Obj instances - this is NOT desired!
Foo foo;
foo.mmap[0] = Obj();
foo.mmap[1] = Obj();
}
int main()
{
mfoo();
// The following line deallocates the memory of the pool just fine -
// but does nothing to prevent the destructors of the Obj instances
// from being called
boost::singleton_pool<boost::fast_pool_allocator_tag,
sizeof(std::pair<int const, Obj>)>::purge_memory();
}
As noted in the code comments, the destructors of the Obj
instances which are managed by the boost::pool
are always called.
What can I do to make the promising quote from the Boost Pool documention, drop them off into oblivion
, come true?