我想为大量对象分配内存。然后逐一构建它们。所以我做了以下几点:
BaseClass* buf = static_cast<BaseClass*> (::operator new (sizeof(BaseClass[5])));
for (int var = 0; var < 5; ++var) {
new (&buf[var]) BaseClass(var);
}
一切似乎都好。但是当我添加删除时:
BaseClass* buf = static_cast<BaseClass*> (::operator new (sizeof(BaseClass[5])));
for (int var = 0; var < 5; ++var) {
new (&buf[var]) BaseClass(var);
// ... do something
delete &buf[var];
}
我收到了“分段错误”错误。在第二次迭代(在构造函数上)。 同时
delete [] buf;
工作正常。
所以问题是 - 为什么会这样?
答案 0 :(得分:4)
Placement new不分配内存,它只调用你给它的内存位置的构造函数。因此您无需删除单个项目。而不是
delete &buf[var];
试试这个,调用析构函数而不释放内存:
buf[var].~BaseClass();
请注意,您仍然需要在整个内存块上使用::operator delete
,而不是在单个对象上。
答案 1 :(得分:4)
首先,如果您使用展示位置new
,则需要明确调用析构函数
buf[var].~BaseClass();
然后你可以删除已经用新分配的东西,而&buf[0]
可以工作,因为它是由贴片new返回的地址,&buf[1]
尚未由内存管理器直接分配{ {1}}。你不能一个一个地释放它们。
所以你应该做类似
的事情::operator new
答案 2 :(得分:2)
您使用delete
而没有相应的new
。使用placement new在先前分配的内存中构造对象不需要成对使用delete
运算符。相反,placement new应与显式析构函数调用配对。由于您直接调用全局operator new
函数,因此您应该将其与直接调用全局operator delete
函数进行配对,而不是使用delete
运算符。
然而,如果这对你所描述的内容是必要的,则没有。以下更容易:
std::vector<BaseClass> buf;
buf.reserve(5);
for (int var = 0; var < 5; ++var) {
buf.emplace_back(var);
}
拥有此对象集合后,您可以将指针指向std::vector<BaseClass*>
:
std::vector<BaseClass*> buf2;
buf2.reserve(buf.size());
std::transform(std::begin(buf), std::end(buf), std::back_inserter(buf2),
std::addressof<BaseClass>);
请确保不要对使指针无效的原始向量执行任何操作。您可以移动它,但不要复制它然后销毁原始文件。