对象在超出范围时是否被销毁,因为它们已引发异常.C++

Are objects destroyed when they go out of scope because an exception has been thrown. C++

本文关键字:因为 C++ 异常 范围 是否 对象      更新时间:2023-10-16

我读到一旦抛出异常,超出范围的对象将被销毁。所以我写了一个代码来测试它。

#include "stdafx.h"
#include <iostream>
using namespace std;
class E {
public:
    int v = 0;
};
void f() {
    E e;
    E *pointer = &e;
    e.v = 7;
    throw pointer;
}
int main(void) {
    E* MainPointer = new E;
    try {
        f();
    }
    catch (E* e) {
        cout << e -> v; //was executed
        MainPointer = e;
    }
    cout << MainPointer->v; //was executed
    system("pause");
    return 0;
}

输出是 77,这意味着捕获块和最终 cout 都被执行了。但是,我预计在最后的cout会出现内存错误,因为MainPointer 指向的对象现在应该已被释放。

有人可以澄清为什么在 f() 中声明的对象没有被解除分配。

你有两个误解,共同创造了这个问题。事实是

  1. 根据标准,当物体的寿命结束时,物体将被销毁。由块内声明的变量呈现的自动存储会在块退出时被销毁,因为标准是这样说的。
  2. 您无法通过检查代码是否有效来检查是否会发生未定义的行为。未定义的行为包括正确(预期)执行程序。

根据(1)在f()内部声明的局部变量e被销毁。根据(2)您可以访问释放的内存,并且可能会获得正确的值。检查e是否被销毁的唯一方法是定义析构函数,以便class E能够跟踪它。将调用析构函数。

在异常期间发生堆栈展开。堆栈上分配的对象将被销毁,但堆上分配的对象不会operator new。您必须手动销毁它们或将它们包装成unique_ptr。

相关文章: