標籤:

不用虛析構函數也不會造成內存泄漏的原因是什麼?

代碼如下:

#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;這句就不會,提請注意的是,這裡的析構函數並非虛函數,從輸出結果也可以看出,程序只調用了基類的析構函數,並未調用派生類的析構函數,那麼顯然派生類的數據並沒有回收,但是從結果上看,系統內存保持一個定值,根本沒有上漲,運行多久都可以。

我當然知道虛析構函數適用於在類內有動態申請內存空間的情況,但是我仍然想不明白這裡的、派生類獨有的內存到底是怎麼回收的。


因為你的數組是棧上的 其次所有非靜態成員都會在調用完析構後按申明次序調用它們的析構


Base* p = new Derive();

其實已經記錄下分配的內存大小的,最後回收的時候自然也會被釋放。你將

Base* p = new Derive;
delete p;

轉化成下面語句就明白了。

// Base* p = new Derive;
void* mem = malloc(sizeof(Derive));
Base* p = new (mem)(Derive);

// delete p;
p-&>~Base();
free(mem);

new 一個對象,可以分解成兩步的,分配內存,再在內存上面調用構造函數構造對象。delete 一個對象,也可以分解成兩步,調用析構函數,再釋放內存。你例子當中,就算是調用 Base 的析構函數,也不影響最終 Derive 內存的分配。

但假如是這樣:

class Derive : public Base
{
public:
Derive()
{
ptr = malloc(100);
}

~Derive()
{
free(ptr);
}
void* ptr;
};

沒有調用 Dervie 的析構函數,就出問題了。


推薦閱讀:

C/C++靜態庫中的函數在這個靜態庫被使用時還有被inline的可能嗎?
為什麼現在有很多人甚至大學授課還在堅持VC6?

TAG:CC | 內存泄露 |