简体   繁体   English

C ++“新”内存分配

[英]C++ “new” memory allocation

I want to allocate memory for a huge bulk of objects. 我想为大量的对象分配内存。 Then construct them one by one. 然后逐一构建它们。 So I do the following: 所以我做了以下事情:

BaseClass* buf = static_cast<BaseClass*> (::operator new (sizeof(BaseClass[5])));
for (int var = 0; var < 5; ++var) {
    new (&buf[var]) BaseClass(var);
}

And everything seems ok. 一切似乎都好。 But when I add delete: 但是当我添加删除时:

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];
}

I got "segmentation fault" error. 我收到了“分段错误”错误。 On second iteration (on constructor). 在第二次迭代(在构造函数上)。 At the same time 与此同时

 delete [] buf;

works fine. 工作正常。

So the question is - why this? 所以问题是 - 为什么这个?

Placement new doesn't allocate memory, it just calls the constructor for the memory location you gave it. Placement new不分配内存,它只调用你给它的内存位置的构造函数。 So you don't need to delete the individual items. 因此您无需删除单个项目。 Instead of 代替

delete &buf[var];

Try this, which calls the destructor without freeing memory: 试试这个,调用析构函数而不释放内存:

buf[var].~BaseClass();

Note that you still need to use ::operator delete on the whole chunk of memory, just not on the individual objects. 请注意,您仍然需要在整个内存块上使用::operator delete ,而不是在单个对象上。

First of all if you use a placement new then you will need to call destructor explicitly 首先,如果您使用new的贴图,那么您将需要显式调用析构函数

buf[var].~BaseClass();

Then you can delete just things that have been allocated with a new, while &buf[0] works since it's the address returned by the placement new, &buf[1] has not been directly allocated by the memory manager through ::operator new . 然后你可以删除已经用new分配的东西,而&buf[0]可以工作,因为它是由placement new返回的地址,而&buf[1]还没有由内存管理器通过::operator new直接分配。 You can't free them one by one. 你不能一个一个地解放他们。

So you should do something like 所以你应该做点什么

::operator delete(buf);

You're using delete without a corresponding new . 您使用的是delete而没有相应的new Using placement new to construct objects in previously allocated memory does not require a paired use of the delete operator. 使用placement new在先前分配的内存中构造对象不需要配对使用delete运算符。 Instead placement new should be paired with explicit destructor calls. 相反,placement new应与显式析构函数调用配对。 Since you're calling the global operator new function directly, you should be pairing that with a direct call to the global operator delete function, rather than using the delete operator at all. 由于您直接调用全局operator new函数,因此您应该将其与直接调用全局operator delete函数进行配对,而不是使用delete运算符。

However none if this is necessary for what you've described. 但是,如果这对您所描述的内容是必要的,则无。 The following is much easier: 以下更容易:

std::vector<BaseClass> buf;
buf.reserve(5);

for (int var = 0; var < 5; ++var) {
    buf.emplace_back(var);
}

After you have this collection of objects you can put pointers to them into a std::vector<BaseClass*> : 拥有此对象集合后,您可以将指针放入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>);    

Just be sure not to do anything to the original vector that invalidates the pointers. 请确保不要对使指针无效的原始向量做任何事情。 You can move it, but don't copy it and then destroy the original. 你可以移动它,但不要复制它然后销毁原件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM