我想利用 boost::fast_pool_allocator
的以下广告功能(请参阅 the Boost documentation for Boost Pool ):
(有关此引用,请参阅 here。)
关键短语是 将它们放入遗忘 中。我不希望在这些对象上调用析构函数。
(原因是我有数百万个小对象,它们在堆上形成了一个极其复杂的所有权网络,当单个最父对象离开堆栈时,我的程序需要大约 20 分钟才能调用所有析构函数。我不需要调用这些析构函数,因为没有所需的副作用,并且所有内存都包含在 boost::pool
中。)
不幸的是,尽管有上述文档的 promise ,以及 boost::pool
概念的 promise ,我还是找不到一种方法来防止调用托管对象的析构函数。
问题很容易在一个小示例程序中隔离:
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();
}
正如代码注释中所指出的,由
Obj
管理的 boost::pool
实例的析构函数总是被调用。我该怎么做才能使 Boost Pool 文档
drop them off into oblivion
中的有希望的报价成为现实? 最佳答案
您将自定义分配器传递到您的 std::map
类中。因此,此分配器将用于 std::map
内部的所有内容:用于所有 Obj
数据以及 std::map
二叉树的节点。结果,如果您在 purge_memory()
的析构函数中调用 Foo
,那么所有这些内存都将变得无效,并且会在 std::map
析构函数中崩溃。
您认为自定义分配器负责对象的解除分配的假设是不正确的:释放所有对象是 std::map
的任务。因此,无论您是通过自定义分配器还是使用默认分配器,都会调用 ~Obj()
。
对于您的问题,我没有看到任何优雅的解决方案。但这种方法应该有效:
placement new
从池的内存中创建 Foo
对象,Foo
对象,purge_memory()
从池中释放所有内存。不会调用析构函数 ~Obj
或 ~std::map
。 关于c++ - 如何防止在 boost::fast_pool_allocator 管理的对象上调用析构函数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22942255/