gpt4 book ai didi

c++ - 关于删除通过 placement new 创建的对象的困惑

转载 作者:搜寻专家 更新时间:2023-10-31 01:01:08 24 4
gpt4 key购买 nike

我不太确定下面的代码中发生了什么:

#include <iostream>

struct Foo
{
double dummy{42};
static void* operator new(std::size_t size, void* p)
{
std::cout << R"(Calling placement "operator new" for size )"
<< size << '\n';
return ::operator new(size, p);
}

Foo()
{
std::cout << "Foo::Foo()" << std::endl;
}
~Foo()
{
std::cout << "~Foo::Foo()" << std::endl;
}
};

int main()
{
void* buf_heap = new char[128] {};
Foo* pFoo_heap = new(buf_heap) Foo; // placement allocation

// why does this line call the correct operator delete?
delete pFoo_heap;

// the line above seems to be equivalent to:
// pFoo_heap->~Foo();
// ::operator delete(buf_heap);
}

我知道每当在构造对象时使用放置 new 时,应该手动调用析构函数,然后调用释放内存(通常通过 ::operator delete::operator delete[],或 free,具体取决于放置 new 的实现方式),参见例如How to delete object constructed via placement new operator?

但是,在我上面的代码中,我创建了一个 Foo 对象,我将它放在堆分配的内存中。然后,当我调用 delete pFoo_heap 时,析构函数会自动调用(我理解这一点),但似乎内存也被释放了(在本例中为 buf_heap)。也就是说,如果我之后尝试执行 ::operator delete[](buf_heap);,我会遇到段错误。

基本上是这样

delete pFoo_heap;

似乎等同于

pFoo_heap->~Foo(); 
::operator delete[](buf_heap);

是否确实如此(或者只是 UB)?为什么在 buf_heap 中分配的内存被取消分配?或者,换句话说,delete pFoo_heap; 是否知道内存来自何处,即使是通过放置 new 分配的?

最佳答案

你问:

// why does this line call the correct operator delete?
delete pFoo_heap;

// the line above seems to be equivalent to:
// pFoo_heap->~Foo();
// ::operator delete(buf_heap);

事实并非如此。您的代码受未定义行为的影响。来自 C++ 标准:

5.3.5 Delete

2 If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion function, and the converted operand is used in place of the original operand for the remainder of this section. In the first alternative (delete object), the value of the operand of delete may be a null pointer value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject (1.8) representing a base class of such an object (Clause 10). If not, the behavior is undefined.

在你的例子中,pFoo_heap 不是由 new-expression 创建的,buf_heap 是由 new-expression< 创建的/em>。您需要使用:

pFoo_heap->~Foo();
delete [] buf_heap;

对于一个行为良好的程序。

关于c++ - 关于删除通过 placement new 创建的对象的困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29709491/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com