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