创建一个作用域定制的内存池/分配器?

4

在C++中,是否可以创建一个自定义分配器,其工作方式仅如下:

{
    // Limit memory to 1024 KB
    ScopedMemoryPool memoryPool(1024 * 1024); 

    // From here on all heap allocations ('new', 'malloc', ...) take memory from the pool.
    // If the pool is depleted these calls result in an exception being thrown.

    // Examples:
    std::vector<int> integers(10);
    int a * = new int [10];
}

我在boost库或其他地方都找不到类似的东西。

这是否存在一些根本性的问题使得这种操作不可能?


1
看一下 Boost.Pool 库。boost::pool_allocatorboost::fast_pool_allocator 可以用作 std::vector 和其他容器的分配器。 - Mike Seymour
5个回答

4

您需要创建一个自定义分配器,并将其作为模板参数传递给vector。这个自定义分配器基本上会包装对您的池的访问,并执行任何大小验证。


2
是的,你可以创建这样的结构,在许多游戏中都被使用,但基本上你需要实现自己的容器并调用你创建的池的内存分配方法。
你也可以尝试为STL容器编写自定义分配器,尽管似乎通常不建议这样做。(我以前做过,感觉很繁琐,但我不记得有任何具体的问题。)
请注意,编写自己的内存分配器并非易事。你可以看一下Doug Lea's malloc,它提供了“内存空间”,你可以在你的作用域结构中以某种方式使用它们。

2
在我看来,OP想要在每个作用域上微调分配器(可能是为了避免编写不同的分配器和创建STL容器特化)。你的情况可能有所不同。 - dirkgently
一般来说,我建议不要尝试使用STL容器与自定义内存分配例程。编写自己的内存分配系统有非常好的理由,但也伴随着相当高的成本。(是的,我看到它们被用于定制分配器行为,而不管它所接收的内容,但是没有标准容器存在,也没有使用newdeletemalloc函数族。) - dash-tom-bang

1
我会回答一个不同的问题。看看“高效C++”这本书。他们讨论的其中一件事是实现这种东西。那是为了一个Web服务器。
对于这个特定的事情,你可以在C++层面上通过覆盖new并提供自定义分配器给STL来进行操作。
或者你可以在malloc层面上进行操作,从自定义malloc开始,并从那里开始工作(例如dmalloc)。

你是指这个吗?-> http://www.amazon.com/Efficient-C-Performance-Programming-Techniques/dp/0201379503 - Billy ONeal

0
这是否存在根本性问题,使得这是不可能的?
讨论程序行为将变得根本上不可能。各种奇怪的问题会出现。代码的某些部分可能会执行或者不执行,但这似乎对接下来的部分没有影响,后者可能会毫无阻碍地工作。某些部分可能总是失败。处理标准库或任何其他第三方库将变得极其困难。有时会发生运行时的碎片化,有时则不会。

3
哦,怎么会这样呢?一个不能处理内存分配失败的库是一个糟糕的库。 - Billy ONeal
重载全局的 newdelete 是一个不好的想法。一般来说,原因如我所述。OP说,在没有可用内存的情况下会抛出异常。请注意,这并不意味着一个作用域中池的内存耗尽必然会影响下一个作用域中定义的池。 - dirkgently

0

如果意图是让该范围内的所有分配都使用该分配器对象,那么它本质上就是一个线程局部变量。

因此,如果使用static或全局变量来实现它,则会存在多线程问题。否则,这是一个不错的解决方案,用于解决分配器的无状态性。

(当然,您需要传递第二个模板参数,例如vector< int, UseScopedPool >。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接