放置删除功能永远不会异常调用

时间:2018-11-30 08:49:29

标签: c++ c++11

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

从未删除过放置删除功能,只是退出了它。为什么?

4 个答案:

答案 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块。