在内存池中用 new 和 delete 替换 malloc 和 free

Posted

技术标签:

【中文标题】在内存池中用 new 和 delete 替换 malloc 和 free【英文标题】:Replace malloc and free by new and delete in a memory pool 【发布时间】:2016-08-05 10:05:50 【问题描述】:

我正在使用一个模板化的内存池,它使用以下联合来存储数据:

union MemoryPoolNode

    MemoryPoolNode *next;
    T data;
;

之前,我使用 malloc 为新节点分配内存:

MemoryPoolNode *node = (MemoryPoolNode*)malloc(sizeof(MemoryPoolNode));

然后释放它:

free(node);

现在,我想用 new 和 delete 替换我对 malloc 和 free 的调用。

为此,为节点分配内存,我现在正在做:

MemoryPoolNode *node = (MemoryPoolNode*)new char[sizeof(MemoryPoolNode)];

然后释放它:

char *toDelete = (char*)node;
delete[] toDelete;

这是正确的做法吗?

union 中的类型 T 可以是具有构造函数和析构函数的类,并且我不希望在为内存池中的新节点分配内存时调用构造函数或析构函数,因为我已经使用了放置new 并且每次弹出一个节点并放回内存池时我都会手动调用析构函数,所以我只想分配和释放内存,就像 malloc 和 free 一样。

仅供参考,我正在替换 malloc 和 free,因为池用于可以覆盖“new”和“delete”以相应分配内存的环境(用户空间、内核等)。

【问题讨论】:

为什么要尝试用 new 和 delete 替换 malloc 和 free?如果您不尝试分配新的有效对象,为什么要调用new 一切都与 malloc 和 free 完美配合。我替换它们的唯一原因是因为内存池在“新”可以被覆盖以不同方式分配内存的环境中工作(用户空间/内核/ ...) 好吧,那么您的方法将不起作用,因为它不会使用自定义的operator new。数组不使用operator new。如果operator new[] 已被覆盖,即使您的联合不是数组,您也将获得数组所需的自定义。 实际上,它们都被覆盖了。 构造MemoryPoolNode 不会构造T。怎么可能?如果它是 Tstd::string 的联合,它怎么知道要构造哪个? 【参考方案1】:

您的代码已损坏,您需要先修复它。

C++11 之前的:

联合不能包含具有非平凡特殊成员函数(复制构造函数、复制赋值运算符或析构函数)的非静态数据成员。

后 C++11:

如果联合包含具有非平凡特殊成员函数(默认构造函数、复制/移动构造函数、复制/移动赋值或析构函数)的非静态数据成员,则默认情况下该函数在联合中被删除并需要由程序员明确定义。

见here。你不遵守任何规则。你需要解决这个问题。

一旦你修复它,你就可以使用node = new MemoryPoolNode()delete node;

对于 C++11,可以这样做:

union MemoryPoolNode

    MemoryPoolNode *next;
    T data;

    MemoryPoolNode() : next(NULL)  ; 
    ~MemoryPoolNode()  ; 
;

【讨论】:

以上是关于在内存池中用 new 和 delete 替换 malloc 和 free的主要内容,如果未能解决你的问题,请参考以下文章

定制new和delete

类重载 new 和 delete vs 放置 new 与定制的内存类

什么是栈区?

第四篇:new和delete的基本用法

转 内存池技术的原理与实现

Java内存分配之堆栈和常量池(转)