C++的陷阱:堆内存中的对象,在程序执行结束后会被调用析构函数么
标题是什么意思? 标题可能有点长,大概是这个意思,我们通过new,在堆内存上创建一个对象,例如:
A *a=new A;
然后不手动delete,那么等到程序执行结束后(main函数被返回),那么对象a的析构函数会被调用么.. 结果到底如何? 昨天我就遇到了这个问题,我问了abreto,他说应该会被调用析构函数,但是通过我的试验,看上去并没有被调用:
#include <iostream>
class A { public: A(char *str):str(str) {}
~A() { std::cout<<str<<std::endl; }
char *str; };
int main() { A *a1=new A("a1");
A *a2=new A("a2"); delete a2;
A a3("a3"); }
输出是:
a2 a3
这在什么情况下会发生?
大体两种情况,一种是程序崩溃,一种是main函数正常被return. 程序崩溃主要就是访问了错误的内存,这时程序会直接退出,不会调用任何对象的析构函数,包括用new申请的堆内存,和在栈上的局部对象。 这可以通过下面的代码实验得到:
int main() { A *a1=new A("a1");
A a3("a3");
int b=0/0; }
上面这段代码没有任何输出 另一种是程序正常结束,这时,main函数中声明在栈上的局部变量会被调用析构函数(因为超出了作用域嘛),而用new申请的堆内存上的对象则不会,除非你在mian函数被return前手动delete它 这意味着什么? 这意味着,如果你需要在new创建的对象的析构函数中进行一些工作,例如保存数据到硬盘上,那么你必须在程序结束前手动delete它,否则它的析构函数将不会被调用
而在使用Qt的时候,你的main函数不得不这么写:OClientCore *core; int main(int argc, char *argv[]) { QApplication a(argc, argv); core=new OClientCore; core->init(); int retrunCode=a.exec(); delete config; delete core; return retrunCode; }
而不是:
OClientCore *core;
int main(int argc, char *argv[]) { QApplication a(argc, argv); core=new OClientCore; core->init();
return a.exec(); }
|