qq906237201 2016-05-01 09:52 采纳率: 57.1%
浏览 1457
已采纳

不用虚析构函数也不会造成内存泄漏的原因是什么?

代码如下:
#include
using namespace std;
class Base
{
public :
Base(){}
virtual void fun(){ cout << "from Base :" << endl; }
~Base(){ cout << "from Base destructor:" << endl; fun(); }
int b;
};
class Derive : public Base
{
public:
Derive(){ }
virtual void fun(){cout << "from Derive :" << endl;}
~Derive(){ cout << "from Derive destructor:" << endl; fun(); }
int asdfasd[100][100][100];

};
int main()
{
while(true)
{
Base *p = new Derive;
delete p;
}

return 0;
}
可以看到派生类比基类多了一个非常大的数组,如果这个数组真的没有回收的话,不用2秒钟,系统内存就满了。
这一点已测试。具体就是把delete p;注释掉,内存使用量咔咔往上涨,不到2秒系统强制停止了该进程。
但是如果加上delete p;这句就不会,提请注意的是,这里的析构函数并非虚函数,从输出结果也可以看出,程序只调用了基类的析构函数,并未调用派生类的析构函数,那么显然派生类的数据并没有回收,但是从结果上看,系统内存保持一个定值,根本没有上涨,运行多久都可以。
我当然知道虚析构函数适用于在类内有动态申请内存空间的情况,但是我仍然想不明白这里的、派生类独有的内存到底是怎么回收的。

  • 写回答

6条回答

  • liyuanbhu 博客专家认证 2016-05-01 13:05
    关注

    "程序只调用了基类的析构函数,并未调用派生类的析构函数,那么显然派生类的数据并没有回收" 这里 “那么显然派生类的数据并没有回收” 是错的。
    数据回收与析构函数其实没有必然关系。 分配在堆栈上的数据当运行出作用域时自动删除,比如你代码中的“int asdfasd[100][100][100];”,这个机制与析构函数无关。

    分配在堆上的数据(也就是 new 出来的数据)需要通过 delete 来删除,也与析构函数无关。只是大家编程习惯喜欢把 delete 写在析构函数里,所以让你有个错觉是析构函数删除了数据。

    总之,析构函数其实就是个普通的函数,无非是编译器替你在需要调用它的地方调用它而已。这个函数在本质上与其他的函数没有任何区别。他也不会替你删除什么数据。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)

报告相同问题?

悬赏问题

  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘