c++ - 为什么在 main 中未捕获异常时不调用析构函数?

标签 c++ exception destructor stack-unwinding

我有以下代码:

#include <iostream>
#include <vector>
#include <tr1/memory>

struct FooError {};

struct Foo
{
    ~Foo() { std::cerr << "~Foo() executed" << std::endl; }
    explicit Foo(unsigned int index) { if (5 == index) throw FooError(index); };
};


int main() {
    typedef std::tr1::shared_ptr<Foo> FooPtr;
    std::vector<FooPtr> foos;
    for (unsigned int index = 0; index < 20; ++index)
    {
        try
        {
            foos.push_back(FooPtr(new Foo(index)));
        }
        catch (const FooError&)
        {
            std::cerr << "FooError caught" << std::endl;
        }
    }
}

我看到一组 ~Foo() 在有 try{} catch{} block 时执行。如果没有异常处理程序,则不会打印任何内容。这是否意味着在处理异常时调用堆栈分配对象的析构函数?或者由于 std::cerr 缓冲问题而没有打印任何内容?

最佳答案

以下是 C++03 标准的详细信息。

  • 从 15.3/9 开始处理异常

    If no matching handler is found in a program, the function terminate() is called;

  • 从18.6.3异常终止:

    The implementation’s default terminate_handler calls abort().

  • 并从 3.6.3/4 终止:

    Calling the function void abort(); declared in <cstdlib> terminates the program without executing destructors for objects of automatic or static storage duration and without calling the functions passed to atexit().

这就是为什么你的 foos对象未被破坏(它具有静态存储持续时间)。但是,即使您将其更改为局部变量(具有自动持续时间),也可能无法解决问题(强调):

所以对于 static duration对象,除非您更改终止处理程序(可能让它调用 exit() 而不是 abort() ),否则不会调用析构函数。但是,对于自动对象,仍然存在一个可能的问题(强调):

15.5.1/1 The terminate() function

In the situation where no matching handler is found, it is implementation-defined whether or not the stack is unwound before terminate() is called. In all other situations, the stack shall not be unwound before terminate() is called.

关于c++ - 为什么在 main 中未捕获异常时不调用析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8553357/

相关文章:

c++ - 根据插入时间从 std::map 中移除元素

c++ - 检测按键按下和按键释放事件

c++ - 发生错误时在 if/else block 之间切换

C++ : What is the Right way to delete a derived class instance?

c++ - 函数参数究竟何时被破坏?

c++ - 阻塞/等待堆栈操作

java - 为什么每次输出都不一样? try catch finally 异常代码

Python 日志记录异常

c++ - 何时在 C++ 中调用要移动到的对象的析构函数?

c++ - 制作 : No rule to make a header file?