Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当对象因引发异常而超出作用域时是否会被销毁。C++;_C++_C++11 - Fatal编程技术网

C++ 当对象因引发异常而超出作用域时是否会被销毁。C++;

C++ 当对象因引发异常而超出作用域时是否会被销毁。C++;,c++,c++11,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* Mai

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

#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;
}
#包括“stdafx.h”
#包括
使用名称空间std;
E类{
公众:
int v=0;
};
void f(){
E;
E*指针=&E;
e、 v=7;
投掷指针;
}
内部主(空){
E*MainPointer=新的E;
试一试{
f();
}
捕获(E*E){
cout v;//已执行
MainPointer=e;
}
cout v;//已执行
系统(“暂停”);
返回0;
}
输出为77,这意味着执行了捕获块和最终cout。然而,我期望在最后一个cout出现内存错误,因为MainPointer指向的对象现在应该已经被释放了


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

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

  • 根据标准,当对象的寿命结束时,对象将被销毁。在块内部声明的变量表示的自动存储在块退出时被破坏,因为标准是这样说的
  • 您不能通过检查代码是否工作来检查未定义的行为是否发生。未定义的行为包括程序的正确(预期)执行

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

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

    您将获得未定义的行为。抛出的指针确实指向某个解除分配的对象,基本上它是一个悬空的指针。在
    MainPointer=e之后
    assignment
    MainPointer
    也会变成悬空指针(还请注意,您泄漏了堆内存)。默认情况下,释放不会产生内存错误!!无法保证解除分配后指向的内存会发生什么情况,但在覆盖之前,它很可能仍然包含以前的数据。是的,引发异常涉及堆栈展开,这意味着所有局部变量都超出范围并被销毁。这意味着您捕获的指针无效,取消引用它将导致错误。然而,话虽如此,真正发生的只是内存还没有被回收或重新使用,所以它仍然保留着它的旧内容。@Someprogrammerdude这不是一个答案而不是一个注释吗?“MainPointer指向的对象现在应该被释放了”为什么?您是否在任何地方调用了
    delete