【发布时间】:2014-05-08 15:32:03
【问题描述】:
如果这个问题太愚蠢,请原谅我。使用 RAII 的最常见示例是:
void func(){
// create some object pointer using any smart pointer
// do some operation that may throw
return;
}
// whether method returns from the *return* statement or because of any exception it is guaranteed that the memory will be released
This article 说(如果我理解正确的话),如果运行时系统知道没有异常处理程序可以在抛出异常后捕获异常它可能跳过调用自动对象的析构函数。
还有一个针对该问题的建议解决方案,即在main 中使用catch(..)。
现在我担心的是,如果不使用建议的 解决方案,那么即使在使用 RAII 之后也可能存在资源泄漏。并且存在无法应用解决方案的情况(例如创建将被其他人使用的库)。在这种情况下,可能会出现严重问题,例如损坏包含有价值信息的文件。
我们真的应该关注这个问题吗?或者我只是错过了什么?
【问题讨论】:
-
如果你的程序崩溃了,你真的认为泄漏是你最大的问题吗?
-
这篇文章我没看过,但是如果没有异常处理程序,是不是程序会被终止,所以资源还是会被释放? (假设它不是像临时文件或数据库锁这样的进程外的东西。)
-
如果我拔掉你的机器,析构函数不会被调用。我是认真的:如果你的析构函数对远程 API 进行查询,你不能假设你会得到完美平衡的锁定/解锁调用!
-
标准的相关部分是15.3/9:如果没有找到匹配的处理程序,则调用函数std::terminate();在此调用 std::terminate() 之前是否展开堆栈是实现定义的。
-
我发现任何涉及需要非平凡清理的资源的操作(删除临时、注销服务器等,任何不能简单地由OS)通常必须在编写时具有强大的异常安全保证,而单独的 RAII 很少是足够的(除了一些聪明的例子)。强大的异常安全通常涉及包含一些清理和回滚代码的包罗万象(或所有可能的异常)。当您只控制资源访问(RAII类)而不是整体操作时,不可能提供强有力的保证。