如何从被称为对提振:: fast_pool_allocator管理对象prevent析构函数? [英] How to prevent destructors from being called on objects managed by boost::fast_pool_allocator?

查看:257
本文介绍了如何从被称为对提振:: fast_pool_allocator管理对象prevent析构函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想借的boost :: fast_pool_allocator (见的为升压池的Boost文档):

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...

(见这里的这句话。)

关键短语的就拿去被人遗忘。我的的想要的析构函数呼吁这些对象。

The key phrase is drop them off into oblivion. I do not want the destructors called on these objects.

(原因是,我有几百万形成堆拥有一个极其复杂的网络微小物体的,它需要我的程序大约20分钟打电话给所有的析构函数时,单亲最对象熄灭的堆叠。我并不需要这些所谓的析构函数,因为没有希望的副作用,所有的记忆都包含在的boost ::池之内。)

(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.)

不幸的是,尽管上述文件的承诺,而的boost ::池理念的承诺,我不能找到一种方法,prevent的析构函数从管理对象被调用。

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();
}

由于在code评论指出,这是由的boost ::池管理的的OBJ 实例的析构函数总是被调用。

As noted in the code comments, the destructors of the Obj instances which are managed by the boost::pool are always called.

我能做些什么,使来自Boost池机制的文档有前途的报价,就拿去被人遗忘,成真?

What can I do to make the promising quote from the Boost Pool documention, drop them off into oblivion, come true?

推荐答案

您通过自定义分配器到的std ::地图类。所以,这个分配器将用于一切的std ::地图里面:所有的OBJ 数据,也为节点的的std ::地图二叉树。其结果是,如果你调用 purge_memory()的析构函数,然后这一切的记忆变得无效,并在崩溃的std ::地图析构函数。

You pass the custom allocator into your std::map class. So, this allocator will be used for everything inside of std::map: for all Obj data and also for nodes of a binary tree of std::map. As the result, if you call purge_memory() in Foo's destructor then all this memory becomes invalid, and it crashes in std::map destructor.

您假设自定义分配器负责对象去分配是不正确的:这是一个的std ::地图的任务来释放所有对象。因此,〜的OBJ()如果您通过自定义分配器或将被称为无论如果你使用一个默认的。

Your assumption that a custom allocator is responsible for objects' de-allocation is not correct: it's a std::map's task to free all objects. So, ~Obj() will be called regardless if you pass the custom allocator or if you use a default one.

我不明白你的问题的任何优雅的解决方案。但是,这种方法应该工作:

I don't see any elegant solution for your question. But this approach should work:


  • 使用配售新以创建从池的内存对象,

  • 使用该对象像往常一样,

  • 通话 purge_memory()来释放从池中的所有内存。没有析构函数〜的OBJ 〜性病::地图将被调用。

  • use placement new to create Foo object from pool's memory,
  • use this Foo object as usual,
  • call purge_memory() to release all memory from the pool. No destructors ~Obj or ~std::map will be called.

这篇关于如何从被称为对提振:: fast_pool_allocator管理对象prevent析构函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆