C++ "new"内存分配
C++ "new" memory allocation
我想为大量对象分配内存。然后一个接一个地建造。所以我做了以下事情:
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;
工作良好。
所以问题是——为什么会这样?
首先,如果使用放置new
,则需要显式调用析构函数
buf[var].~BaseClass();
然后,您可以只删除已经用new分配的东西,而&buf[0]
工作,因为它是放置new返回的地址,&buf[1]
没有由内存管理器通过::operator new
直接分配。你不能一个接一个地解放他们。
所以你应该做一些类似的事情
::operator delete(buf);
Placement new不分配内存,它只调用您给它的内存位置的构造函数。因此,您不需要删除单个项。代替
delete &buf[var];
试试这个,它在不释放内存的情况下调用析构函数:
buf[var].~BaseClass();
请注意,您仍然需要在整个内存块上使用::operator delete
,只是不需要在单个对象上使用。
您使用的delete
没有相应的new
。使用placement new在先前分配的内存中构造对象不需要成对使用delete
运算符。相反,placementnew应该与显式析构函数调用成对出现。由于您直接调用全局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>);
只是要确保不要对原始向量执行任何使指针无效的操作。你可以移动它,但不要复制它,然后销毁原来的。
相关文章:
- 在c++中为我自己的基于指针的数组分配内存的正确方法
- 给定一个指向堆分配内存的指针,智能指针实现如何为其找到合适的释放函数?
- 如果 const 不分配内存,为什么我可以获取 const 的地址?
- 在函数中分配内存时出现问题
- 如何为 std::vector 分配内存,然后稍后为某些元素调用构造函数?
- constexpr new 如何分配内存?
- 在构造函数中分配内存失败是如何冒泡的
- LLVM 传递以在特定地址分配内存
- CudaMalloc 在分配内存时失败
- 为什么它在不分配内存的情况下工作正常
- 为什么在正确解除分配内存时出现内存泄漏?
- 如何通过 malloc 为队列数组分配内存?
- vector是否为std::移动的对象连续分配内存
- 删除类成员的动态分配内存的最佳方法是什么
- 唯一指针是否在堆或堆栈上分配内存?
- 如果不分配内存,我如何能够为变量创建和分配值?
- std::initializer_list 堆是否分配内存?
- 如何按顺序或在指定的地址分配内存?
- 是否可以使用 malloc 为类对象分配内存?
- 迭代器是否分配内存(如指针)?