【问题标题】:Can I back a boost intrusive collection using boost pool as storage?我可以使用提升池作为存储来支持提升侵入式集合吗?
【发布时间】:2014-09-18 16:27:29
【问题描述】:

我了解 boost 侵入式集合最终会存储对对象的引用,因此对象需要自己的生命周期管理。

我想知道我是否可以简单地使用提升池来管理该生命周期。当我想在 boost 侵入列表中存储一个新对象时,我可以从 boost 池中分配一个对象并将其存储在列表中吗?然后,当我从列表中删除时,我使用 boost pool 解除分配。

【问题讨论】:

    标签: c++ boost object-lifetime intrusive-containers


    【解决方案1】:

    答案是肯定的。

    这也不是很典型。

    如果你想控制何时和哪里内存被分配,你可以使用一个池。

    如果您想将数据结构的内存布局与其语义解耦,请使用侵入式容器。

    所以,有一个甜蜜点,但它看起来更像:

    • 用侵入式钩子装饰元素类型(例如侵入式地图)
    • 您在某种类型的“最佳”内存布局中创建新元素(这很可能是 vector<MyElement, custom_allocator>)

    散文:

    • 然后当我从列表中删除时,我会使用提升池解除分配

      一个典型的使用池的场景是当你想/不/必须释放元素时(当心非平凡的析构函数)。否则,你只是将堆本地的低效率移到池中(碎片,锁定)

    • 对象需要自己的生命周期管理

      这听起来有点不对劲。事实上,对象不需要有“自己的”生命周期管理。只是他们的生命周期不受他们参与的侵入式数据结构的支配。

      例如通过将所有元素存储在一个向量中,您可以获得连续存储,并且所有元素的生命周期都由向量[1] 控制。因此,您可以将元素生命周期和分配与容器语义解耦


    [1] 任何与向量重新分配有关的问题通常都可以通过预先预留足够的容量来防止。如果你这样做了,你会意识到这与固定大小的池分配器非常相似,但增加了零碎片的保证。如果你不需要后者,你可以做一个list<T, pool_allocator<T> >,这样你就可以获得引用的位置,但在插入/删除时引用稳定。等等等等。

    【讨论】:

    • 我认为 boost::pool 可能优于向量,因为它在分配和释放节点时隐式处理内存。
    • @NathanDoromal 在向量或双端队列方面有什么区别?
    • 不同之处在于当我们到达vector或deque的末尾,需要分配更多的节点。隐式都使用分配器并且都使用额外的动态内存,除非使用自定义分配器,否则它们本身不会被跟踪。通过使用 Boost 池,我摆脱了这种额外的管理,并且最干净地一次性处理了生命周期管理和动态内存管理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-28
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多