gpt4 book ai didi

c++ - 如何防止在 boost::fast_pool_allocator 管理的对象上调用析构函数?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:53:34 25 4
gpt4 key购买 nike

我想利用 boost::fast_pool_allocator 的以下广告功能(参见 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...

(有关此引述,请参阅 here。)

关键短语是让他们消失。我希望在这些对象上调用析构函数。

(原因是我有数百万个微小的对象,它们在堆上形成了一个极其复杂的所有权网络,当单个父级对象离开堆栈。我不需要调用这些析构函数,因为没有预期的副作用,所有内存都包含在 boost::pool 中。)

不幸的是,尽管上述文档和 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();
}

如代码注释中所述,boost::pool 管理的 Obj 实例的析构函数始终被调用。

我能做些什么来实现 Boost Pool 文档中的 promise ,让它们消失,成为现实?

最佳答案

您将自定义分配器传递到您的 std::map 类中。因此,此分配器将用于 std::map 内的所有内容:用于所有 Obj 数据以及 std::map 的二叉树的节点。结果,如果您在 Foo 的析构函数中调用 purge_memory(),那么所有这些内存都会变得无效,并且它会在 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com