在placement new中发生异常时,placement delete用于取消分配内存。所以我进行了测试:
#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;
}
从未删除过放置删除功能,只是退出了它。为什么?
答案 0 :(得分:5)
您的程序将引发未捕获的异常。这意味着std::terminate
被调用。
在这种情况下,可能不会出现堆栈展开(是否发生这种情况由实现定义)。您的实现显然决定不进行堆栈展开就调用std::terminate
。
operator delete
的调用实际上是stack unwinding的一部分,即使此处不涉及堆栈,也有点用词不当。
要查看您的函数正在被调用,请将代码更改为:
try
{
A* a = new(o) A;
}
catch(...) {}
。
答案 1 :(得分:2)
那是因为您没有捕获异常,所以没有调用与您删除相关的代码。只需将其包装在GenericForeignKey
/ try
块中即可:
catch
请注意,您必须有效地捕获构造函数引发的异常,而不仅仅是任何异常。
答案 2 :(得分:1)
如果正确处理了异常,则放置位置operator delete
的{{3}}。
如果您不处理该异常,则允许实现在throw
时立即终止您的程序,而无需展开堆栈,例如is being called。
答案 3 :(得分:0)
class A {
public:
A(){
cout << "constructor" << endl;
throw 1;
}
void* operator new(size_t size, int i){
cout << "in placement new" << endl;
return ::new A();
}
void operator delete(void *ptr){
cout << "in placement delete" << endl;
::operator delete(ptr);
}
};
int main(){
int o = 9;
try
{
A* a = new(o) A;
}
catch(...)
{
cout << "Exception"<< endl;
}
}
最好在类级别使用重载运算符。另外,您必须使用try / catch块。