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 c程序不知道为什么得不到结果
  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置