13

我有如下代码

try {
  doSomething();
} catch(InterruptException) {
  goto rewind_code;
}

if(0) {
rewind_code:
  longjmp(savepoint, 1);
}

我的问题是,当我goto离开 catch 块时,C++ 运行时存储的异常对象是否被释放?或者运行时是否允许缓存它,直到周围的函数存在或类似的东西?我只是想确保如果我多次执行上述代码,每次使用倒带代码时,我都不会泄漏内存(因为longjmp不会执行编译器在函数序言中或之前发出的清理代码)。

4

2 回答 2

11

§6.6/2:

从范围退出时(无论如何完成),都会为所有具有自动存储持续时间的构造对象调用析构函数(12.4)......

至少正如我所读到的那样,“无论多么成功”应该/确实包括一个goto.

编辑:好的,根据约翰内斯的评论,我们关心的是§15.1/4:

当为异常执行的最后一个处理程序以 throw 以外的任何方式退出时;临时对象被销毁,实现可以为临时对象释放内存;

[ ... ]

销毁在处理程序的异常声明中声明的对象销毁后立即发生。

于 2011-08-31T20:32:50.240 回答
4

§ 15.1.4

异常对象的内存以未指定的方式分配,除非在 3.7.4.1 中注明。如果一个处理程序通过重新抛出而退出,则控制权将传递给另一个处理程序以处理相同的异常。异常对象在异常的最后一个剩余活动处理程序以除 rethrowing 以外的任何方式退出,或引用异常对象的 std::exception_ptr (18.8.5) 类型的最后一个对象被销毁后销毁,以较晚者为准. 在前一种情况下, 销毁发生在处理程序退出时,在处理程序的异常声明中声明的对象(如果有)销毁之后立即发生。在后一种情况下,销毁发生在 std::exception_ptr 的析构函数返回之前。然后实现可以为异常对象释放内存;任何此类解除分配都是以未指定的方式完成的。

于 2011-08-31T20:57:31.330 回答