1

由于系统限制,假设我只能从堆中分配内存一次(例如使用std::allocator或其他更通用的 C++11 兼容分配器)。

这种单一分配将占用很大的内存块。然后我想使用容器和动态内存,但都限于先前分配的内存块。

我设法编写了一个非常简单的分配器,它逐渐“提供”内存移动指针。在这个分配器deallocate中是无操作的,并且来自块的内存不会返回到块。显然可以做得比这更好。换句话说,我想要一个托管堆。

按顺序重用此块内存是一个难题,因为需要管理不连续的空闲段、碎片整理、(可选)线程安全等。

这个图案叫什么名字?有一段时间我认为这是一个池分配器,但它似乎指的是其他东西(重用小对象)。

我可以使用 C++ 的哪些功能或标准库来实现和管理此类分配,或者至少可以毫不费力地构建自己的?

我希望能在 Boost 中找到一些东西。但是 Boost.Pool 是另外一回事,看起来像这样的东西是在 Boost.Interprocess 中为特定目的而实现的,但它似乎并不容易使用,而且我很难在它们的原型使用之外理解它(例如进程间共享内存。)

否则,我发现的最接近的是这个https://www.boost.org/doc/libs/1_41_0/libs/pool/doc/interfaces/pool_alloc.html,但似乎::new可以多次调用。

示例代码:

int main(){
    UserBlockAllocator<double> a(new double[1000], 1000); 
    {
        std::vector<double, UserBlockAllocator<double>> v0(600, a);
    } // v0 returns memory to block managed by a
    std::vector<double, UserBlockAllocator<double>> v1(600, a);
    std::vector<double, UserBlockAllocator<double>> v2(600, a); //out of memory
}
4

1 回答 1

2

这种模式被称为arena allocatorstack allocator。如果我正确理解这些std::pmr东西,astd::pmr::monotonic_buffer_resource与此有关,但我从未尝试过。

使用这些关键字,您可以找到一些东西,但我没有使用这些工具的经验。

请注意,很容易成功地解除分配最近的分配。

一个强大的模式是分配器的组合,正如 Andrei Alexandrescu 在 CppCon 2015 上的一个有趣的演讲中所描述的那样。如果你想构建自己的工具,你可以考虑在你的FreeListAllocator( 35:42 ) 之上组合StackAllocator( 43:18 ) )。这样,您可以解决如何管理不连续的空闲段的问题(如您所描述的那样)。

于 2018-08-11T15:03:39.977 回答