關(guān)于內(nèi)存泄露的問題(解決+剖析)
首先先闡明這篇隨筆的意圖,只在告訴讀者,內(nèi)存泄露的神不知鬼不覺,希望能引起大家的注意。
一段代碼的意思如何正確表達(dá),才能不造成內(nèi)存泄露呢?很多朋友經(jīng)常泄露了內(nèi)存但卻查找不到原因。當(dāng)然在CLI/C++中利用托管對(duì)象堆上的垃圾收集器是可以更好地避免這一點(diǎn)。但是在更早的版本中,程序員有必要去手動(dòng)刪除這些相關(guān)資源。否則將在程序關(guān)閉的時(shí)候出現(xiàn)一些錯(cuò)誤。
MFC
現(xiàn)在我們?nèi)ブ剌d一個(gè)虛函數(shù)virtualvoidDeleteContents();用來在銷毀文檔數(shù)據(jù)前調(diào)用框架刪除一些文檔類的數(shù)據(jù),(MSDN:Called by the framework to delete the document's data without destroying the CDocument object itself.)
先批評(píng)一段代碼:
void
?CGraphicDoc::DeleteContents()?2
{3
????
for
(
int
?i
=
0
;i
<
m_obArray.GetSize();i
++
)4
????
{5
????????……
6
????}
7
????CDocument::DeleteContents();8
}
優(yōu)化:
void?CGraphicDoc::DeleteContents()??2


{?3
????int?nCount;?4
????nCount=m_obArray.GetSize();?5
????for(int?i=0;i<nCount;i++)?6

????
{?7
????????……?8
????}?9
????CDocument::DeleteContents();10
}填寫for循環(huán)內(nèi)的語句。這里的任務(wù):刪除之前利用CObArray : m_obArray對(duì)象保存的一個(gè)指針?biāo)赶虻膶?duì)象,以及指針本身。因此(以下提供幾種常見的錯(cuò)誤代碼)
代碼A:
void?CGraphicDoc::DeleteContents()??2


{?3
????int?nCount;?4
????nCount=m_obArray.GetSize();?5
????for(int?i=0;i<nCount;i++)?6

????
{?7
????????delete?m_obArray.GetAt(i);???//刪除對(duì)象指針?biāo)赶虻膶?duì)象?8
????????m_obArray.RemoveAt(i);???//刪除對(duì)應(yīng)的指針本身?9
????}10
????CDocument::DeleteContents();11
}
void?CGraphicDoc::DeleteContents()??2


{?3
????int?nCount;?4
????nCount=m_obArray.GetSize();?5
????for(int?i=0;i<nCount;i++)?6

????
{?7
????????delete?m_obArray.GetAt(i);?8
????????m_obArray.RemoveAt(0);?9
????}10
????CDocument::DeleteContents();11
}因此有人突發(fā)奇想:如果我每次只刪除第0個(gè)數(shù)據(jù)的話,那么是否就可以了呢?于是代碼B誕生了。可是問題終究沒能得到解決。因?yàn)榧僭O(shè)有一組數(shù)據(jù)一共3個(gè)。刪除了編號(hào)0的元素(delete語句),移除了該元素的指針,此時(shí)i=1,進(jìn)入刪除,又到了delete語句,這時(shí)候刪除元素i=1這樣的語句,這時(shí)實(shí)際上是刪除了先前元素中的第二個(gè)元素,而不是第一個(gè)。而0與2中間的第1個(gè)元素則未被刪除。又出現(xiàn)了隱含問題。其實(shí)只要將兩個(gè)都改為0,每次都刪除第一個(gè)就可以了。
void?CGraphicDoc::DeleteContents()??2


{?3
????int?nCount;?4
????nCount=m_obArray.GetSize();?5
????for(int?i=0;i<nCount;i++)?6

????
{?7
????????delete?m_obArray.GetAt(0);?8
????????m_obArray.RemoveAt(0);?9
????}10
????CDocument::DeleteContents();11
}
void?CGraphicDoc::DeleteContents()??2


{?3
????int?nCount;?4
????nCount=m_obArray.GetSize();?5
????while(nCount--)?6

????
{?7
????????delete?m_obArray.GetAt(nCount);?8
????????m_obArray.RemoveAt(nCount);?9
????}10
????CDocument::DeleteContents();11
}12

void?CGraphicDoc::DeleteContents()??2


{?3
????int?nCount;?4
????nCount=m_obArray.GetSize();?5
????for(int?i=0;i<nCount;i++)?6

????
{?7
????????delete?m_obArray.GetAt(i);?8
????}?9
????m_obArray.RemoveAll();10
????CDocument::DeleteContents();11
}posted on 2006-08-16 03:44 volnet 閱讀(4203) 評(píng)論(5) 編輯 收藏 引用

