C++中Delete时堆错误(Heap Corruption)的原因
最近這三四天一直在跟一個bug做斗爭:程序在運行過程中死掉,Output窗口顯示:
? ? ? ? 1.Windows has triggered a breakpoint in ***,?This may be due to a corruption of the heap...
? ? ? ? 2.Access violation reading location...
? ? ? ? 今天下午終于找到了真正的原因。那也就順便把關(guān)于這個問題Google到的知識總結(jié)一下:
?
? ? ? ??
? ? ? ? 這些問題均有可能代表程序中出現(xiàn)了堆錯誤。
? ? ? ? 而出現(xiàn)堆錯誤的原因主要有 以下兩大類:
?
? ? ? ? 首先是工程設(shè)置方面的問題:
? ? ? ? 1.在dll中申請的內(nèi)存(new)在exe中釋放了(delete),這時有可能會報堆錯誤;這時需要在dll中導(dǎo)出一個用于釋放內(nèi)存的函數(shù);
? ? ? ? 2.在一個dll中申請的內(nèi)存,在另一個dll中釋放;而這兩個dll使用的運行時庫不同。這時可以如1一樣確保哪個模塊申請的內(nèi)存就在那個模塊釋放,也可以將兩個工程的運行時庫設(shè)置成同一個,即MD(d)或者M(jìn)T(d);
?
? ? ? ? 第二類是代碼邏輯中的問題:
? ? ? ? 1.同一塊地址的指針被釋放(delete)了兩次,會導(dǎo)致以上錯誤。一般地,在每次釋放內(nèi)存之后,都將相應(yīng)指針設(shè)置為NULL,并在delete指針之前進(jìn)行檢查,可以避免這種問題;
? ? ? ? 2.內(nèi)存申請之后,又對相應(yīng)指針進(jìn)行了改變,例如自增的(++)操作,使得指針沒有指向內(nèi)存塊的首地址,也會出現(xiàn)這種錯誤。一般地,在申請到內(nèi)存后需要指針運算的,拷貝一份指針變量進(jìn)行運算,而原指針變量則保持不變。
?
? ? ? ? 我遇到的問題是屬于第二類的第一種,但是涉及到了多線程的問題,比較隱蔽。具體是這樣的:
? ? ? ? 有四個隊列A1,A2,B1,B2,有兩個線程需要通過一個類D的函數(shù)將A1,A2中的數(shù)據(jù)取出來,并復(fù)制一份,放入B1,B2。我在類D中定義了一個成員變量M用于臨時存放A1,A2中的數(shù)據(jù)。當(dāng)?shù)谝粋€線程將A1中數(shù)據(jù)賦給M之后,還沒有將M放入B1之前,可能第二個線程就把M又賦成了A2中的數(shù)據(jù)。這樣最后存放入B1,B2就是同一份數(shù)據(jù),也就是兩個指針指向了同一塊內(nèi)存。這樣,在釋放內(nèi)存的時候,就會出現(xiàn)delete兩次同一塊內(nèi)存的情況了。
? ? ? ? 這種情況下,給成員變量M加鎖,或者使用兩個成員變量分別對應(yīng)兩個線程,都可以解決這個問題。
? ? ? ? ? ? 歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明出處http://ushertechblog.sinaapp.com/post-27.html
總結(jié)
以上是生活随笔為你收集整理的C++中Delete时堆错误(Heap Corruption)的原因的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MFC框架类、文档类、视图类相互访问(及
- 下一篇: CString::GetBuffer函数