6

早些時候,我遇到了C(Visual Studio)中的動態內存問題。 我有一個或多或少的工作程序,釋放一個緩衝區時拋出運行時錯誤。這是一個明顯的內存損壞,該程序寫在緩衝區的末尾。調試內存損壞

我的問題是,追查非常耗時。錯誤在損壞後被拋出,我不得不手動調試整個運行,以找出緩衝區末端何時被覆蓋。

有什麼工具可以幫助追蹤這個問題嗎?如果該程序就會立即崩潰,我會發現問題快了很多......

問題的例子:

int *pNum = malloc(10 * sizeof(int)); 

//     || 
//     \/  
for(int i = 0; i < 13; i++) 
{ 
pNum[i] = 3; 
} 

// error.... 
free(pNum); 
+0

是不是這種什麼'緩衝區安全檢查'編譯器選項罪VS? – stijn

+4

不要使用神奇數字? – phant0m

+5

@ phant0m它不是真正的代碼,它是一個例子,也不是我的代碼......緩衝區是基於數據大小動態分配的,而計算它大小的函數有一個小錯誤... 除了我的問題是關於追蹤問題,而不是阻止它... –

回答

3

我用pageheap。這是微軟改變分配器工作方式的工具。使用pageheap時,當您調用malloc時,分配將四捨五入到最近的頁面(一塊內存),並在其後面放置一個設置爲不可讀/不可寫的虛擬內存頁面。您分配的動態內存已對齊,以便緩衝區的末尾位於虛擬頁面之前的頁面末尾之前。這樣,如果你經過緩衝區的邊緣(通常是單個字節),調試器可以很容易地捕獲它。

2

是否有任何工具\方式,以協助追查此問題?

是的,這正是靜態代碼分析器試圖找到的錯誤的類型。例如splint/PC-Lint

下面是這些工具的列表: http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis

編輯:在嘗試夾板上您的代碼段,我得到以下警告:

的main.c:9: 2:可能的越界商店:pnum [i]

想必這個警告會幫助你。

3

我使用「數據斷點」。在你的情況下,當程序崩潰時,它可能會首先抱怨這樣的:

堆塊在00397848在0039789C過去的修改要求的4C

大小,然後,重新啓動您的程序,並設置數據斷點在地址0039789C。當代碼寫入該地址時,執行將停止。經常發生這種情況,我立即發現錯誤。

如果你的程序分配,並多次釋放內存,它正好處於這個確切的地址,只是禁用解除分配:

_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_DELAY_FREE_MEM_DF); 
0

我們的CheckPointer工具可以幫助找到內存管理錯誤。它適用於GCC 3/4和Microsoft的C語言。

許多動態檢查程序只捕獲一個對象的外部外部,然後只有當該對象是堆分配。 CheckPointer會發現內存訪問錯誤裏面的是一個堆分配對象;無論字段類型是什麼,訪問結構中字段的結尾都是非法的;大多數動態檢查器無法檢測到這種錯誤。它還會發現離本地人很近的地方。