在自定义内存管理器中使用矢量

using a vector in a custom memory manager

本文关键字:自定义 内存 管理器      更新时间:2023-10-16

我正在用c++编写一个内存管理器。其目的是在开始时使用malloc分配一定数量的内存,然后重载new和delete,以便它使用该内存。我几乎有它的工作,我唯一的问题是我如何保持跟踪什么是在哪里的记忆。

我创建了一个结构体向量,它保存了诸如大小,位置以及是否空闲等信息。

问题是当我调用push_back时,它试图使用我重载的新函数。这就是它失败的地方,因为它不能使用重载的new,直到它推回第一个信息结构。

有人知道我如何解决这个问题或更好的方法来跟踪内存吗?

不要重载全局operator new !

最简单的和(WARNING;主观->)的最佳解决方案是定义您自己的Allocator,您将在处理自由存储上的分配时使用它。堆)。所有STL容器都支持将AllocatorType作为模板参数传递。

重载全局operator new/operator delete似乎是一个整洁的解决方案,但我几乎可以向您保证,随着开发的进行,它将给您带来麻烦。

在这个自定义的分配器中,你可以跟踪什么去了哪里,但使内部std::vector(或任何你想使用的,std::map似乎更适合我)将使用默认的operator new/operator delete


如何创建自己的分配器?

下面的链接会引导你到一个很好的文档,里面有关于这件事的信息:

  • stdcxx.apache.org -构建您自己的分配器(强烈推荐)

在需要/需要时使用自定义分配器将使遇到任何鸡和蛋问题,当尝试为分配内存的分配器分配内存时,但是分配器必须已经分配了内存才能使用分配器方法。除了分配器之外,还有什么会为分配器分配内存呢?我们需要为那个分配器分配内存那个分配器必须有它自己的分配器,尽管分配器需要内存,由另一个分配器提供?

也许我应该养只狗,它们不下蛋,对吧?

创建一个类并只在这个类中重载new。向量不会有问题。您将能够在::new A上使用自己的new,在new A上使用正常的new

class C
{
public:
void* operator new( size_t n ) ;
// ...
} ; 
否则,可以使用自己的操作符函数,而不是重载operator new:

分配器的基本概念:

int *i = myGetMem(i); // and myGetMem() allocates sizeof(*i) bytes of memory.

所以你在使用向量时不会有问题。


实际上,一个真正的内存分配器将你放在vector上的信息保存在分配给它的内存中:

你可以使用getmem/freemem的算法来适应你的情况。这很有帮助。

。:我想分配10个字节,@1024的内存包含有关分配的内存的信息,分配器在1024之后返回一个地址,也许@1030(取决于存储的信息)作为分配内存的开始。所以用户得到地址1030,他的内存在1030到103A之间。

当调用deallocator时,使用开始的信息来正确释放内存并将其放回可用内存列表中。

(可用内存的列表按照流行的算法存储在一组自由内存的链表中,这些链表按大小组织,并使用算法来避免和最小化碎片)

这可以解决你对矢量的需求。

您可以使用任何自定义分配器创建向量。

以如下方式声明:

std::vector<YourStruct, YourOwnAllocator> memory_allocations;

YourOwnAllocator将是一个类,它将分配向量所需的数据,绕过你的重载操作符。它需要提供这里列出的所有方法和类型。