我知道为单个对象创建一个内存池很容易,但是我需要为数组创建一个内存池。我目前拥有的内存池具有一个指向相邻内存块的地址 vector ,以及一个指向这些内存块中每个对象的堆栈,因此,当您从池中进行分配时,您只是弹出堆栈,而当您释放时,您只需将对象的地址压入回到它。但是,我还需要一个等效的数组。像这样:

template<typename T>
class ArrayPool
{
public:
ArrayPool();
~ArrayPool();

T* AllocateArray(int x); //Returns a pointer to a T array that contains 'x' elements.
void FreeArray(T* arr, int x); //Returns the array to the free address list/stack/whatever/
};

这样的事情实现了吗?我想象有一个这样的池会带来很大的问题-如果确保由ALlocateArray返回的数组在内存中是连续的,那么我基本上会像没有内存池那样做。只是当场分配数组。对于普通的对象池,每次我只分配1个对象。有了数组,我每次都可以分配一个大小不同的数组,因此一旦释放了数组,它就不会与新的大小不同的数组兼容,除非我将数组和一些类似链表的结构固定在一起,但是他们赢了不连续。

最佳答案

当前,您的分配器利用了所有分配大小相同的事实。这简化并加速了分配和释放,并且意味着内存碎片是不可能的。

如果必须分配任何大小的数组,则所需的是通用分配器,而不是池分配器。接下来要做什么取决于您为什么首先使用池分配器。我可以想到池分配器的其他两个功能可能是相关的,并且可能还有其他功能:

  • 所有内存都来自创建池
  • 时指定的特定区域
  • 通过重置池,可以一次释放所有内存,而无需释放每个单独的分配。

  • 如果您不需要自己控制分配的任何特殊功能,则只需使用vector或全局operator newmalloc来分配您的内存。如果确实需要特殊功能,则可能需要取消分配器的配置,而不是自己实现。如果您真的想详细了解一个好的内存分配器如何工作,请查看http://g.oswego.edu/dl/html/malloc.html并使其适应您的使用。

    但是,如果您确实确实需要为有限的目的而手动分配器,则基本思想是,需要一个包含空闲块的数据结构(您选择的是什么),而不是总是可以从中获取空闲节点的列表,大小不同的对象,可让您快速找到足够大的块来满足当前请求。在更大的情况下,您可以选择拆分块,返回一部分,并将其余部分保留为新的较小的空闲块。在两个空闲块相邻的情况下,您可以选择将它们合并为一个更大的空闲块。

    一种常见的策略是保留某些大小的块状池列表(例如16、32、64 ...)。如果请求足够小,请使用以下方法之一满足要求。如果不是,请执行更复杂的操作。但是正如我说的,如果您想看到很多技巧,那么请看一下dlmalloc。

    关于c++ - 是否可以实现与数组而不是单个对象一起使用的内存池?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22042770/

    10-11 21:51
    查看更多