我正在尝试实现自己的std::vector
容器,我正在使用realloc()
来调整它,以防止每次删除和重新分配。使用以下代码:
buffer = new T[n]();
这将默认初始化数组的每个元素,并允许我立即开始访问它们。但是,由于标准指定要使用must be previously allocated by malloc(), calloc() or realloc()
的内存realloc()
,因此我无法使用new
。
我知道calloc()
会对内存进行零初始化,但我不确定它是否与new T[n]()
具有相同的行为。使用C样式内存分配进行默认初始化的正确方法是什么?
答案 0 :(得分:3)
首先,不,零初始化内存与调用该内存应该容纳的对象的默认构造函数不同。您必须调用构造函数。因此malloc
与calloc
在正确性方面并不重要;所以,如果你要去那条路线,请使用malloc
- 它会更快。
其次,realloc
不会直接工作,因为它不知道如何复制对象。某些对象可以逐字节复制,对于这些类型,realloc
是可以的。但对于大多数类型,复制涉及其他操作,您必须使用复制构造函数或复制赋值运算符来执行复制。所以realloc
可以用于特殊情况,但不是一般情况。
因此,您实际上仅限于malloc
和free
,以及构造函数(通过展示位置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应该是安全的。