虚析构函数与内存泄露
2013-01-30 12:36
197 查看
#include <iostream> using namespace std; class father { public: father():a(50){;} ~father(){cout<<"父亲的析构函数"<<endl;} int a; }; class son:public father { public: son():b(50){;} ~son(){cout<<"儿子的析构函数"<<endl;} int b; }; void main() { father *p = new son; delete p; }在main函数中如上代码所示,我们用一个父指针指向子类对象,然后用delete释放掉。这样会造成内存泄露吗?书上说,由于父指针指向了子对象,如果父类析构函数不声明为虚函数,那么,delete时,只会调用父类析构函数,不会调用子类析构函数。那么,可能造成内存泄露。上面的代码编译运行后发现,确实,子类析构函数并没有被调用。但会不会造成内存泄露呢?实践是检验真理的唯一标准,我把main函数里的代码改为:
system("pause"); father *p = new son[1000000]; delete []p; system("pause");
运行发现,内存并没有泄露。那为什么书上说可能泄露呢,注意,“可能!”。我把代码改为:
#include <iostream> using namespace std; class father { public: father():a(50){;} ~father(){;} int a; }; class son:public father { public: son(){b=new int(50);} ~son(){delete b;} int *b; }; void main() { system("pause"); father *p = new son[1000000]; delete []p; system("pause"); }
运行后发现,内存泄露了!为什么呢?注意我们在子类构造函数了new了一个int,本来我们需要用子类析构函数来delete的,但是由于main函数里delete []p时只调用了父类析构函数,没有调用子类析构函数,所以子类析构函数里的delete没有执行,就内存泄露了。我们把上面代码改一改,在父类析构函数前加个virtual声明为虚函数。
#include <iostream> using namespace std; class father { public: father():a(50){;} virtual ~father(){;} int a; }; class son:public father { public: son(){b=new int(50);} ~son(){delete b;} int *b; }; void main() { system("pause"); father *p = new son[1000000]; delete []p; system("pause"); }
运行发现,并没有发生内存泄露!原来是这样,书上说的可能发生内存泄露,“可能”,注意是“可能”。当子类析构函数里有delete时,由于析构函数不是虚函数,main函数里的父指针指向的是子类对象,delete父指针时只调用了父类析构函数而没有调用子类析构函数,子类析构函数中的delete没有被执行,所以就内存泄露了。但析构函数声明为虚函数后,delete父指针时,既调用了子类析构函数也调用了父类析构函数。子类析构函数中的delete被执行,就没有发生内存泄露。
相关文章推荐
- 内存泄露之虚析构函数(转载)
- 虚析构函数与内存泄露
- linux下内存泄露检测工具Valgrind介绍
- [转]关于内存泄露测试工具
- Jprofile(二) - 查找内存泄露
- C#防止内存泄露的方法
- 内存泄露
- 学会用Clang来进行内存泄露分析
- 分析内存泄露
- OpenCV中回调函数中的内存泄露
- 内存泄露及检测
- shared_ptr的缺陷:内存泄露
- VC:快速侦测断言错误导致的内存泄露
- 对话框背景真正起作用的做法。(有内存泄露,不过可以通过各个控件的CtrlColor方法实现)
- Java内存泄露
- [转] Objective-C内存管理 调试内存泄露
- android内存泄露的问题
- App调试内存泄露之Context篇(上)
- 内存泄露检测工具【VLD v2.2.3】
- Android中使用Handler造成内存泄露的分析和解决