2009-10-28 41 views
1

當使用malloc,如果它產生的錯誤一個核心轉儲:ç的malloc問題(MEM腐敗)

malloc(): memory corruption: ....... *** 

這是否意味着嘗試的malloc分配內存,這不是免費分配?如果是這樣的原因是什麼?

+1

編譯器和操作系統? – 2009-10-28 18:19:40

+0

可能是在您調用'malloc'之前某處出現的UB導致的結果。 – dirkgently 2009-10-28 18:23:34

回答

16

它完全依賴於你的malloc實現,但通常這意味着,在malloc之前的某個時間點,向malloced緩衝區寫入了比其大小更多的數據。

換句話說很多malloc實現存儲一些與他們的記憶他們的數據內聯的:

+--------------------------------+ 
|14 bytes -> Padding    | 
+--------------------------------+ 
|2 bytes -> Internal malloc info | 
+--------------------------------+ 
|6 bytes -> Your data   | 
+--------------------------------+ 
|8 bytes -> Padding    | 
+--------------------------------+ 
|2 bytes -> Internal malloc info | 
+--------------------------------+ 

因此,如果您或您的圖書館的一些代碼,寫了16個字節到6字節的緩衝區,將覆蓋填充和內部malloc信息的2個字節。當你下一次調用malloc時,它會嘗試遍歷它的數據來尋找空間,碰到被覆蓋的空間,而且它會覆蓋它並破壞堆,這將是荒謬的。

根據實施情況,這樣的錯誤也可能由雙免費造成。

+0

注意:它不要求你重寫先前從malloc本身獲得的內存 - 只是*某處*覆蓋了malloc試圖在調用它時使用的內存結構。你可能在你的代碼的任何部分(或包含的庫)中有一個緩衝區溢出,因爲沒有要求我知道malloc從一個單獨的池中取出內存而不是新的。他們可能分享相同的堆。即使他們沒有,通過定義。你的應用程序必須能夠訪問由malloc處理的內存,並且任何隨機的ptr寫入都可能會損壞malloc的內部結構 – Mordachai 2009-10-28 18:31:42

+0

由於曾經在OS上工作並花費大量時間在malloc實現中工作,意味着C庫代碼上的所有內容。無可否認,代碼在c庫中也有malloc錯誤,所以你的觀點在這種情況下依然存在。 – 2009-10-28 18:35:46

+0

對於ASCII藝術+1! – Bill 2009-10-28 19:37:59

5

這樣做的通常的原因是,你寫了數據的malloc()不給你寫權限了 - 無論是緩衝區溢出(寫入超出你給予的空間的末尾)或緩衝欠載(前寫緩衝區的開始)。

它有時可能是由釋放未由malloc()等分配的指針或通過重新釋放(double freeing)由malloc()分配的指針引起的。例如,釋放一個靜態緩衝區是一個壞主意;你會得到腐敗。

您應該假設問題出現在您的代碼中 - 這在malloc()等中是不太可能成爲問題的,而且不太可能存在於您正在使用的任何其他庫中。

11

很可能,這在malloc本身中不是問題。相反,這是您的應用程序修改堆不應該部分的問題。

如果您在Linux上運行,請嘗試使用Valgrind來查看哪些代碼將垃圾堆放在您的堆上。

+0

對於Valgrind的建議+1。該程序可以識別程序中最常見的與內存相關的問題。 – 2010-05-29 01:57:58

1

您能否提供您的malloc()語句?

此外,我想仔細檢查返回值是否爲空?

除了沒有分配內存以外,我在使用malloc()new時遇到的問題類似於您提到的實際產生損壞的堆的性質。我通常在程序中的其他地方發現了一些「有趣」的代碼,像memcpy()這樣的字符緩衝區導致緩衝區溢出和地址空間變形。

-bn

2

有幾件事情是堆損壞的通常原因是:

  • 超越內存分配(寫入過去的分配塊的結尾)
  • 雙重釋放塊
  • 指針釋放後使用指針
  • 當然還有一些錯誤地通過與先前的a無關的指針寫入llocation('ram hit'或流氓指針) - 這是包含以上所有內容的一般情況。

這些問題可能很難調試,因爲原因和結果經常被時間和空間(不同的代碼區域)分開。所以直到永久(在計算機時間內)通過導致問題執行的錯誤後纔會發現該錯誤。

使用調試堆可以非常有助於調試這些問題。微軟的編譯器在調試版本中啓用了CrtDebug heap(但可以設置其他配置項)。我不確定GCC有什麼開箱即用的功能,但有些工具可以幫助我通過諸如Valgrind and Electric Fence的傳遞。最後有大量的home-grown heap debug libraries可能有幫助(谷歌周圍)。

+0

+ 1爲理由清晰可讀的列表。 – 2009-10-29 00:48:36