placement delete用于在placement new中发生异常时释放内存。所以我做了一个测试:
#include <iostream>
#include <new>
using namespace std;
class A {
public:
A(){
cout << "constructor" << endl;
throw 1;
}
};
void* operator new(size_t size, int i){
cout << "in placement new" << endl;
return ::operator new(size);
}
void operator delete(void *ptr, int i){
cout << "in placement delete" << endl;
::operator delete(ptr);
}
int main(){
int o = 9;
A* a = new(o) A;
}位置删除函数从来没有被调用过,它只是退出了。为什么?
发布于 2018-11-30 17:11:47
你的程序抛出一个未捕获的异常。这意味着调用了std::terminate。
在这种情况下,可能会有堆栈展开,也可能没有堆栈展开(这是由实现定义的)。您的实现显然决定在不展开堆栈的情况下调用std::terminate。
operator delete的调用实际上是stack unwinding的一部分,尽管这里没有涉及堆栈,但这有点用词不当。
要查看正在调用的函数,请将代码更改为:
try
{
A* a = new(o) A;
}
catch(...) {}。
发布于 2018-11-30 17:12:41
这是因为您没有捕捉到异常,所以不会调用用于删除的相关代码。只需将其封装在try/catch块中:
try
{
int o = 9;
A* a = new(o) A;
}
catch (int i) { }请记住,您必须有效地捕获构造函数引发的异常,而不仅仅是任何异常。
发布于 2018-11-30 17:15:21
如果您正确处理异常,则会显示placement operator delete finction is being called。
如果您不处理异常,则允许实现在throw时立即终止您的程序,而无需展开堆栈,例如,no destructors are called。
https://stackoverflow.com/questions/53554133
复制相似问题