淺析C/C++內存泄漏的解決辦法


使用C/C++語言開發的軟件在運行時,出現內存泄漏。可以使用以下兩種方式,進行檢查排除。

⑴ 使用工具軟件BoundsChecker,BoundsChecker是一個運行時錯誤檢測工具,它主要定位程序運行時期發生的各種錯誤。它通過駐留在集成開發環境內部的自動處理調試程序來加速應用程序的開發,縮短產品發布時間。BoundsChecker對於編程中的錯誤(大多數是C++中特有的)提供了清晰的詳細的分析。它能夠檢測和診斷出,在靜態堆棧內存中的錯誤以及內存和資源泄漏問題。在集成開發環境下,調試運行DEBUG版程序,BoundsChecker在運行時檢測內存泄漏,並在可能出現內存泄漏的代碼處中斷程序運行,開發人員可根據調用現場狀態,排除內存泄漏。

⑵ 調試運行DEBUG版程序,運用以下技術:CRT(C run-time libraries)、運行時函數調用堆棧、內存泄漏時提示的內存分配序號(集成開發環境OUTPUT窗口),綜合分析內存泄漏的原因,排除內存泄漏。

首先,需要在程序中包含以下語句,用來啟用調試堆函數(注:語句的順序是固定的)

[cpp]  view plain  copy
 
  1. #define CRTDBG_MAP_ALLOC  
  2. #include <stdlib.h>  
  3. #include <crtdbg.h>  


其次,設置內存泄漏檢測報告。使用以下語句,在程序結束后,自動調用_CrtDumpMemoryLeaks方法,在OUTPUT窗口中報告內存泄漏的相關信息

[cpp]  view plain  copy
 
  1. _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);  

 

最后,根據OUTPUT窗口中提示的內存泄漏相關信息,排除泄漏。分兩種情況。

情況一、比較簡單。程序退出時,在OUTPUT窗口中,直接報告:出現內存泄漏的源代碼文件名及具體代碼行數。只需要分析此處代碼,根據上、下文修改,一般就可以正確釋放內存了。例如:

Detected memory leaks!

Dumping objects ->

C: \MyProjects\LeakTest\LeakTest.cpp(20): {18} normal block at 0x00780E80, 64 bytes long.

Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD

Object dump complete.

C: \MyProjects\LeakTest\LeakTest.cpp(20)

情況二、比較麻煩。錯誤報告沒有映射到源文件。可使用_CrtSetBreakAlloc方法來檢查定位內存泄漏位置。

例如: 

Detected memory leaks!

Dumping objects ->

{18} normal block at 0x00780E80, 64 bytes long.

Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD

Object dump complete.

注意到報告中的一個信息:{18}。大括號中的這個整數值代表了內存分配順序號。這個例子中,{18}代表了第18次內存分配操作發生了泄漏。在程序運行時,_CrtSetBreakAlloc方法可以在指定的內存分配次數時中斷程序。使用這種方式獲得的信息,比在程序退出時獲得文件名及行號更有價值。因為報告內存泄漏文件名及行號,獲得的只是靜態信息,而_CrtSetBreakAlloc則是把整個現場恢復,可以通過對函數調用棧的分析、以及使用其他在線調試技巧,來分析產生內存泄漏的原因。_CrtSetBreakAlloc要求你的程序執行過程是可還原的(即:多次執行過程的內存分配順序不會發生變化),這個假設在多數情況下成立。不過,在多線程的情況下,這個要求有時難以保證。但是雖然內存分配順序號是變化的,但是變化的順序號卻總是那幾個,也就是說,對某個位置的內存泄漏,多運行幾次程序,內存分配的順序號很可能會重復。所以,多線程環境下,也可以使用_CrtSetBreakAlloc方法來定位內存泄漏。具體操作步驟如下:

①先在調試狀態下運行幾次程序,觀察內存分配順序號是哪幾個值。
②用出現次數最多的那個順序號來設斷點。即:在代碼中添加如下調用:_CrtSetBreakAlloc(18);(假設: OUTPUT窗口中,報告{18}最多。即:第18次內存分配出現泄漏的情況較常發生)
③在調試狀態下運行程序,在斷點停下時,打開"調用堆棧"窗口,找到對應發生內存泄漏的源代碼。
④退出程序,觀察OUTPUT窗口的內存泄漏報告,看本次內存分配的順序號是不是和預設值(_CrtSetBreakAlloc中設置的值)相同,如果相同,就找到了;如果不同,就重復步驟3,直到相同。
⑤最后根據分析結果,在適當的位置釋放分配的內存。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM