vc 記憶體管理

2021-05-26 01:10:42 字數 1464 閱讀 9587

利用vc++環境的除錯和診斷功能,檢查和發現常見記憶體缺陷

理解常見的記憶體缺陷問題以及在vc++環境下的症狀,能輔助我們減少問題的發生和及時修改問題。

從錯誤的表現形式上看, 和堆疊有關的錯誤主要分為兩大類:堆疊溢位和函式返回資訊被破壞。

(1)堆疊溢位(overflow)

此類錯誤主要有兩種情形:

1)過大的區域性變數。預設情況下windows為每個執行緒保留1m堆疊空間。在選單project->properties->configuration properties -> linker->system中可以看到stack reserve size選項可以調整保留的堆疊空間大小。

2)遞迴呼叫層數過深。在除錯過程中,呼叫堆疊(call stack)視窗中可以發現函式遞迴呼叫的模式。

(2)函式返回資訊被破壞

此類錯誤主要有兩種情形:

1)對區域性變數的寫操作超出了範圍(上溢)。在除錯過程中,函式堆疊被破壞掉的明顯標誌是無法顯示呼叫堆疊,並且錯誤發生在被呼叫函式即將返回的位置。

2)在呼叫函式和被呼叫函式之間如果出現了函式引數的不匹配或者呼叫規範的不一致。

為了檢查此類錯誤,應該在**編譯時開啟/gs、/rtcs開關(在選單project->properties->configuration properties-> c/c++->code generation下設定)。

另外一類錯誤是動態記憶體錯誤。典型的情況如下:

(1)記憶體寫越界。在除錯版本中,如果是寫上溢,就會收到「damage:after block...」的跟蹤訊息,如果是寫下溢位就會收到「damage: before block...」的跟蹤訊息。

(3)多次釋放。在除錯版本中,如果多次刪除同一指標, 會收到_block_type_is_valid斷言錯誤。要防止此類錯誤,應在delete某個指向動態記憶體的指標後立即將其置為空。

4 利用windows結構化異常處理機制處理發布版本軟體的記憶體崩潰

在程式的發布階段,應儘量減少程式錯誤尤其是記憶體崩潰。如果崩潰了,應該「優雅」地退出,盡量收集程式崩潰時的執行資訊以幫助程式**商後續的除錯。要捕捉記憶體非法訪問並獲知非法訪問的指令位址、暫存器內容等資訊,需要用到windows的結構化異常處理(structured exception handling,seh)機制[6]。minidumpwritedump是dbghelp.dll提供的乙個 api函式(參考msdn),用於轉儲使用者模式程式的一些資訊(比如堆疊情況等)並存為乙個檔案(比如.dmp檔案),此檔案可以被微軟的偵錯程式(vc++或者windbg)利用進行事後除錯。使用此函式需要dbghelp.h、dbghelp.lib和dbghelp.dll(這些檔案可以在windows platform sdk中找到)。

要事後根據.dmp檔案除錯**,需要為發布版本軟體產生debug symbols (pdb)檔案(開啟編譯器/debug選項)。在拿到.dmp檔案以後,用vc++開啟.dmp檔案,然後除錯執行(按f5鍵)。這樣,崩潰現場就會重現。文獻[5]基於上述的方法實現了崩潰報告系統。

VC6記憶體管理malloc(1)

vc6程式main之前和之後的示意圖 call stack 執行前核心先呼叫maincrtstartup 函式,heap alloc base 函式對記憶體分配有兩種情況,小於1016位元組,呼叫 sbh alloc block,管理小記憶體。大於1016位元組使用windows呼叫heapallo...

VC6記憶體管理malloc(2)

heap init呼叫後,呼叫 ioinit,第一次進行記憶體呼叫malloc,申請256位元組,在debug模式,使用malloc dbg函式。之後呼叫 nh malloc dbg,nh malloc dbg呼叫 heap alloc dbg。對256位元組的記憶體申請,還需要加上額外的管理資訊,...

VC 記憶體申請

問題 如果要申請一塊記憶體?應該如何做?解答 在vc 一般的做法是 lpvoid pvdata 宣告乙個任何型別的指標 dword dwfilesize 申請記憶體的大小 分配全域性的可移動的記憶體 hglobal hglobal globalalloc gmem moveable,dwfilesi...