有一天有個(gè)同事在通過(guò)vld調(diào)試一個(gè)內(nèi)存泄漏問(wèn)題,折騰了很久然后找到我。我瞥了一眼他的代碼,發(fā)現(xiàn)問(wèn)題和我曾經(jīng)遇到的一模一樣:
1 class Base {
2 public:
3 ~Base();
4 };
5
6 class Derived : public Base {
7 privated:
8 std::vector<int> m_data; };
9
10 Base *obj = new Derived();
11 delete obj;
當(dāng)然,實(shí)際代碼比這個(gè)復(fù)雜得多(這也是導(dǎo)致從發(fā)現(xiàn)問(wèn)題到找到問(wèn)題耗費(fèi)大量時(shí)間的原因)。vld在報(bào)內(nèi)存泄漏時(shí),當(dāng)然報(bào)的位置是new
的地方。這個(gè)同事檢查了這個(gè)對(duì)象的整個(gè)生命周期,確定他正確地釋放了這個(gè)對(duì)象。
問(wèn)題的關(guān)鍵就在于:Base
類的析構(gòu)函數(shù)不是virtual
的。因?yàn)椴皇?/span>virtual
,所以在對(duì)一個(gè)Base
類型的指針進(jìn)行delete
時(shí),就不會(huì)調(diào)用到派生類Derived
的析構(gòu)函數(shù)。而派生類里的析構(gòu)函數(shù)會(huì)用于析構(gòu)其內(nèi)部的子對(duì)象,也就是這里的m_data
。這樣,就造成了內(nèi)存泄漏。
這其實(shí)是一個(gè)很低級(jí)的失誤。但毫不客氣地說(shuō)C++中有很多這種少個(gè)關(guān)鍵字或者代碼位置不對(duì)就會(huì)造成另一個(gè)結(jié)果的例子。事實(shí)上,針對(duì)這些悲劇也有很多書(shū)提出一些準(zhǔn)則來(lái)讓大家去無(wú)腦遵守。例如針對(duì)這個(gè)例子,我就記得曾有書(shū)說(shuō),只要你覺(jué)得你的類會(huì)被繼承,那么最好給析構(gòu)函數(shù)加上virtual。
posted on 2012-09-14 13:54
王海光 閱讀(422)
評(píng)論(0) 編輯 收藏 引用 所屬分類:
C++