当对象超出范围时会被销毁,因为抛出了异常。 C ++

时间:2017-10-14 15:36:14

标签: c++ c++11

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

#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,意味着catch块和最终cout都被执行了。但是我期待最后一个cout的内存错误,因为MainPointer指向的对象现在应该被释放了。

有人可以澄清为什么在f()中声明的对象没有被释放。

2 个答案:

答案 0 :(得分:2)

你有两个误解,共同创造了这个问题。真相就是那个

  1. 根据标准,物体的寿命终止时会被摧毁。由块内部声明的变量呈现的自动存储在块退出时被销毁,因为标准是这样说的。
  2. 您无法通过检查代码是否有效来检查是否发生了未定义的行为。未定义的行为包括正确(预期)执行程序。
  3. 根据(1)e内部声明的局部变量f()被销毁。根据(2),您可以访问释放的内存,并且您可以获得正确的值。检查e是否被销毁的唯一方法是定义class E的析构函数以便能够跟踪它。析构函数将被调用。

答案 1 :(得分:0)

在异常发生时堆栈展开。在堆栈上分配的对象被销毁但是使用operator new在堆上分配的对象没有。您必须手动销毁它们或将它们包装到unique_ptr