其他分享
首页 > 其他分享> > c – 为什么在析构函数中抛出异常时未调用重载删除?

c – 为什么在析构函数中抛出异常时未调用重载删除?

作者:互联网

我编写了下面的代码,它重载了new和delete操作符,并在析构函数中抛出异常.

抛出异常时,为什么delete操作符中的代码没有执行(并且“bye”打印)?

如果不应该执行,(如何)释放内存?是one of the other delete operators被叫?是否会重载其中一个而导致执行相应的代码?或者内存根本没有被释放,因为破坏失败意味着它可能不应该是?

#include <iostream>
using namespace std;
class A
{
public:
    A() { }
    ~A() noexcept(false) { throw exception(); }
    void* operator new (std::size_t count)
    {
        cout << "hi" << endl;
        return ::operator new(count);
    }
    void operator delete (void* ptr)
    {
        cout << "bye" << endl;
        return ::operator delete(ptr);
    }
    // using these (with corresponding new's) don't seem to work either
    // void operator delete (void* ptr, const std::nothrow_t& tag);
    // void operator delete (void* ptr, void* place);
};

int main()
{
    A* a = new A();
    try
    {
        delete a;
    }
    catch(...)
    {
        cout << "eek" << endl;
    }
    return 0;
}

输出:

hi
eek

Live demo.

我看着:

> throwing exceptions out of a destructor
> How does C++ free the memory when a constructor throws an exception and a custom new is used
>和其他人

但是我无法找到答案,确切地说(1)析构函数中的异常(而不是构造函数)和(2)重载删除.

我不需要在析构函数中抛出异常的演讲是不好的做法 – 我只是碰到了类似的代码,我对这种行为感到好奇.

如果存在这样的引用,我希望得到标准或类似引用支持的答案.

解决方法:


standard Draft N4296 5.3.5,第121页说:

[expr.delete] [ Note: The deallocation function
is called regardless of whether the destructor for the object or some element of the array throws an exception.
— end note ]

因此,必须在析构函数抛出的情况下调用operator delete.

但是,正如评论中所显示的那样,某些编译器没有正确地调用运算符删除.这可以作为bug编译器来解决.

Bug测试:

> GCC 4.8
> Visual Studio 2015

标签:c,c11,destructor,exception,delete-operator
来源: https://codeday.me/bug/20191007/1868756.html