C++“新”内存分配
Posted
技术标签:
【中文标题】C++“新”内存分配【英文标题】:C++ "new" memory allocation 【发布时间】:2013-12-05 21:06:42 【问题描述】:我想为大量对象分配内存。然后一个一个地构造它们。所以我做了以下事情:
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;
工作正常。
所以问题是 - 为什么会这样?
【问题讨论】:
最好以较小的批量分配动态内存。你的记忆越碎片化,你的新记忆失败的机会就越大。 你为什么不直接使用std::vector<BaseClass>
?
【参考方案1】:
首先,如果你使用一个展示位置new
,那么你需要显式调用析构函数
buf[var].~BaseClass();
然后你可以只删除已经用 new 分配的东西,而&buf[0]
可以工作,因为它是放置 new 返回的地址,&buf[1]
还没有被内存管理器通过::operator new
直接分配。你不能一个一个地释放它们。
所以你应该做类似的事情
::operator delete(buf);
【讨论】:
【参考方案2】:Placement new 不分配内存,它只是调用你给它的内存位置的构造函数。因此,您无需删除单个项目。而不是
delete &buf[var];
试试这个,它调用析构函数而不释放内存:
buf[var].~BaseClass();
请注意,您仍然需要在整个内存块上使用::operator delete
,而不是在单个对象上。
【讨论】:
另见this post。【参考方案3】:您使用的是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>);
请确保不要对使指针无效的原始向量做任何事情。你可以移动它,但不要复制它然后破坏原件。
【讨论】:
我需要一个指向数组元素的指针。比 - 如果我将 std::vector以上是关于C++“新”内存分配的主要内容,如果未能解决你的问题,请参考以下文章
C++ new的时候,为啥会存在内存分配会失败的情况?啥导致的呢?