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

代码如下:
#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;这句就不会,提请注意的是,这里的析构函数并非虚函数,从输出结果也可以看出,程序只调用了基类的析构函数,并未调用派生类的析构函数,那么显然派生类的数据并没有回收,但是从结果上看,系统内存保持一个定值,根本没有上涨,运行多久都可以。
我当然知道虚析构函数适用于在类内有动态申请内存空间的情况,但是我仍然想不明白这里的、派生类独有的内存到底是怎么回收的。

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

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

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

Base *p在其生命范围外会释放;
析构函数的调用是先派生类后基类的

delete p;时
基类析构函数没执行,你可以看到
cout << "from Base destructor:" << endl; fun(); 等都没有执行
但是由于,基类并没有动态分配资源,所以没有资源泄漏
但是,基类的析构函数没被执行,这只怕仍然不是你想要的

debug一下吧

 int _tmain(int argc, _TCHAR* argv[])
{
    while(true)
    {
        Derive *p_drive = new Derive;
        Base *p = p_drive;
        delete p;
    }
    return 0;
}

delete p;时
只是执行了基类析构函数,派生类析构函数没执行,
但是你的派生类,并没有申请动态内存,因此也不存在资源泄露
只是析构函数仅仅执行一半,而且是后一半(仅仅执行了基类的析构函数)
如果你的派生类,申请资源的话,没有机会释放,因为派生类自己的析构函数没有机会执行

C++ new,new[] 内存分配,分两步
1)分配内存 //这一步只有内存大小是有用的,按照类型需要的大小分配内存
2)构造对象 //这一步调用构造函数,所有信息都是有用的

C++ delete,delete[] 释放内存,也分两步
1)析构对象 //这一步析构对象,对于delete[] 要按照每个元素大小逐一析构对象,所以 所有信息都是有用的
2)释放内存 //这一步只有对象地址是有用的。