异常情况下的智能指针析构函数

Smart pointer destructors under exceptional circumstances

在阅读 C++ 中的智能指针时,大部分信息都带有警告:

"Be warned that a smart pointer destructor will (may) not be called in circumstances like an abnormal exit (by calling std::abort or std::exit()), or when an exception propagates out of a thread's primary function or when a method declared noexcept throws an exception".

我的问题是,在所有这些情况下,程序最终都会终止,在这种情况下,当进程的页表被清除时,智能指针指向的内存被 OS 收回(我知道 C++ 标准不讨论页表和虚拟内存,但我在这里提到它是因为这是大多数 OSes 的标准做法)。

那么为什么会发出这个警告呢?如果不调用析构函数,可能发生的最糟糕的事情是什么?或者这是我在使用智能指针管理内存以外的资源时需要注意的警告?如果是,那么这些资源是什么?

正如我在评论中所说的那样,标准所讨论的情况是不应该发生的特殊情况。如果发生这种情况,您的程序将无法正常运行的可能性非常高。所以它被终止了,标准不保证所有的析构函数都被正确调用。

解决办法是防止这种情况发生。

abnormal exit (by calling std::abort or std::exit())

不要调用 abortexit。让所有调用的函数 return 并让 main 执行 return.

or when an exception propagates out of a thread's primary function

捕获 main 中的所有异常。然后return。或者,如果没有全局对象,您也可以 abort.

or when a method declared noexcept throws an exception".

不要加入 noexcept 函数。

可能出现的问题不仅仅与内存有关。删除它持有的指针的智能指针会触发它指向的对象的析构函数。该对象可能持有外部资源。例如,这些可以是一个文件(或套接字),在关闭之前应该刷新(写出缓冲 I/O)。它也可能是一些低级硬件相关的东西,比如 GPIO,例如在操作期间打开灯并在析构函数中关闭它。