如何默认初始化而不使用新的?

时间:2018-01-03 16:26:14

标签: c++

我正在尝试实现自己的std::vector容器,我正在使用realloc()来调整它,以防止每次删除和重新分配。使用以下代码:

buffer = new T[n]();

这将默认初始化数组的每个元素,并允许我立即开始访问它们。但是,由于标准指定要使用must be previously allocated by malloc(), calloc() or realloc()的内存realloc(),因此我无法使用new

我知道calloc()会对内存进行零初始化,但我不确定它是否与new T[n]()具有相同的行为。使用C样式内存分配进行默认初始化的正确方法是什么?

2 个答案:

答案 0 :(得分:3)

首先,不,零初始化内存与调用该内存应该容纳的对象的默认构造函数不同。您必须调用构造函数。因此malloccalloc在正确性方面并不重要;所以,如果你要去那条路线,请使用malloc - 它会更快。

其次,realloc不会直接工作,因为它不知道如何复制对象。某些对象可以逐字节复制,对于这些类型,realloc是可以的。但对于大多数类型,复制涉及其他操作,您必须使用复制构造函数或复制赋值运算符来执行复制。所以realloc可以用于特殊情况,但不是一般情况。

因此,您实际上仅限于mallocfree,以及构造函数(通过展示位置new)和析构函数。

答案 1 :(得分:0)

您可以使用以下语法调用任何类型内存的构造函数:

::new (ptr) T(...arguments go here (if any)...);

您可能必须使用

#include <new>

它会调用T的构造函数来获取在ptr分配的内存。 对于一个数组,你将不得不循环:

T* ptr=(T*)malloc(sizeof(T)*n);
for(int i=0;i<n;++i)
   ::new(ptr+i) T();

但有了这个,请不要打电话删除!您必须为每个项显式调用析构函数,然后使用正确的函数释放内存:

for(int i=0;i<n;++i)
   (ptr+i)->~T();
free(ptr);

如果是realloc,您必须确保可以毫无问题地重新定位T对象(字节到字节的复制OK)。对于具有简单数据类型的struct应该是安全的。