本文介绍了如何正确释放由placement new分配的内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读,当你使用 placement new ,那么你必须手动调用析构函数。

I've been reading somewere that when you use placement new then you have to call the destructor manually.

考虑下面的代码:

   // Allocate memory ourself
char* pMemory = new char[ sizeof(MyClass)];

// Construct the object ourself
MyClass* pMyClass = new( pMemory ) MyClass();

// The destruction of object is our duty.
pMyClass->~MyClass();

至于我知道operator delete 调用析构函数然后释放内存,对吧?那么为什么我们不使用 delete

As far as I know operator delete normally calls the destructor and then deallocates the memory, right? So why don't we use delete instead?

delete pMyClass;  //what's wrong with that?

在第一种情况下,我们不得不将pMyClass设置为 nullptr 我们调用析构函数后像这样:

in the first case we are forced to set pMyClass to nullptr after we call destructor like this:

pMyClass->~MyClass();
pMyClass = nullptr;  // is that correct?

但是析构函数没有释放内存,对吗?
那么这是一个内存泄漏吗?

BUT the destructor did NOT deallocate memory, right?So would that be a memory leak?

我很困惑,你能解释一下吗?

I'm confused, can you explain that?

推荐答案

使用 new 运算符做两件事,它调用函数 operator new 内存,然后使用placement new,在该内存中创建对象。 delete 运算符调用对象的析构函数,然后调用 operator delete 。是的,名字很混乱。

Using the new operator does two things, it calls the function operator new which allocates memory, and then it uses placement new, to create the object in that memory. The delete operator calls the object's destructor, and then calls operator delete. Yeah, the names are confusing.

//normal version                   calls these two functions
MyClass* pMemory = new MyClass;    void* pMemory = operator new(sizeof(MyClass));
                                   MyClass* pMyClass = new( pMemory ) MyClass();
//normal version                   calls these two functions
delete pMemory;                    pMyClass->~MyClass();
                                   operator delete(pMemory);

由于在您的情况下,您手动使用展示位置,您还需要手动调用析构函数。由于您手动分配内存,您需要手动释放它。记住,如果你使用 new 分配,必须有一个相应的 delete

Since in your case, you used placement new manually, you also need to call the destructor manually. Since you allocated the memory manually, you need to release it manually. Remember, if you allocate with new, there must be a coressponding delete. Always.

但是,placement new设计为使用内部缓冲区(以及其他情况),其中缓冲区不是 operator new ,这就是为什么你不应该调用 operator delete

However, placement new is designed to work with internal buffers as well (and other scenarios), where the buffers were not allocated with operator new, which is why you shouldn't call operator delete on them.

#include <type_traits>

struct thingy {
    std::aligned_storage<sizeof(MyClass)>::type buffer;
};
int main() {
    thingy a;
    MyClass* pMyClass = new (&a.buffer) MyClass(); //created _inside_ thingy a
    //stuff
    pMyClass->~MyClass(); //can't use delete, because there's no `new`.
    return 0;
}

thingy的目的 class是以任何方式创建和销毁存储器,而 main 负责构建/销毁 MyClass

The purpose of the thingy class is to create and destroy the storate in whatever way, while main takes care of the construction/destruction of MyClass, note how the two are (almost*) completely separate from each other.

这篇关于如何正确释放由placement new分配的内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 16:50