什麼是內存泄漏?app
內存泄漏(memory leak),指因爲疏忽或錯誤形成程序未能釋放已經再也不使用的內存的狀況。內存泄漏並不是指內存在物理上的消失,而是應用程序分配某段內存後,因爲設計錯誤,失去了對該段內存的控制,於是形成了內存的浪費。編輯器
C和C++內存泄露函數
對於C和C++這種沒有Garbage Collection 的語言來說,咱們主要關注兩種類型的內存泄漏:編碼
堆內存泄漏(Heap leak)。對內存指的是程序運行中根據須要經過malloc,realloc, new等從堆中分配的一塊內存,完成後必須經過調用對應的 free或者delete 釋放掉。若是程序設計的錯誤致使這部份內存沒有被釋放,那麼此後這塊內存將不會被使用,就會產生Heap Leak.spa
系統資源泄露(Resource Leak)。主要指程序使用系統分配的資源好比 Bitmap,Handle,SOCKET等沒有使用相應的函數釋放掉,致使系統資源的浪費,嚴重可致使系統效能下降,系統運行不穩定。設計
如何解決內存泄露?調試
內存泄露的問題其困難在於:code
一、編譯器不能發現這些問題。對象
二、運行時才能捕獲到這些錯誤,這些錯誤沒有明顯的症狀,時隱時現。blog
三、對於手機等終端開發用戶來講,尤其困難。
下面從三個方面來解決內存泄露:
第一,良好的編碼習慣,儘可能在涉及內存的程序段,檢測出內存泄露。當程序穩定以後,再來檢測內存泄露時,無疑增長了排除的難度和複雜度。
使用了內存分配的函數,要記得要使用其釋放函數釋放掉。
Heap memory:
malloc\realloc ------ free
new \new[] ---------- delete \delete[]
GlobalAlloc------------GlobalFree
Resource Leak :
對於系統資源使用以前要仔細看其使用說明,防止錯誤使用或者忘記釋放掉系統資源。
對於基於引用計數的系統對象尤爲要注意,由於只有其引用計數爲0時,該對象才能正確被刪除。而其使用過程當中又生成的新的系統資源,使用完畢後,若是沒有及時刪除,都會影響其引用計數。
使用Visual Leak Detector for Visual C++
簡介
Visual Leak Detector是一款免費的、健全的、開源的Visual C++內存泄露檢測系統。相比Visual C++自帶的內存檢測機制,Visual Leak Detector能夠顯示致使內存泄露的完整內存分配調用堆棧。
使用方法
VLD簡單易用,文檔也很豐富,對於內存泄露的具體位置也能以調用堆棧的形式詳細的顯示出來。
下載安裝後,僅僅須要告訴Visual C++在哪裏找到include文件和lib文件。
C/C++ -> General -> Additional Include Directories = C:\Program Files (x86)\Visual Leak Detector\include
Linker -> General -> Additional Library Directories = C:\Program Files (x86)\Visual Leak Detector\lib\Win32
Linker -> Input-> Additional Dependencies = vld.lib
而後,在代碼上的變更就只須要簡單的加上#include <vld.h> 就能夠了。
當你在Visual C++中調試運行你的程序時,在程序結束後VLD將在output窗口輸出一個內存泄露報告,該報告包括了你的程序中內存分配的完成調用棧信息。雙擊調用棧的某一行,就能夠迅速跳轉到你的代碼編輯器相應的位置。
Visual Leak Detector有一些配置項,能夠設置內存泄露報告的保存地(文件、調試器),拷貝"\Visual Leak Detector"路徑下的vld.ini文件到工程的Debug目錄下(在IDE運行的話,則須要拷貝到工程目錄下),修改如下項:
ReportFile = .\memory_leak_report.txt
ReportTo = both
能夠看到在Debug目錄下生成文件memory_leak_report.txt,跟VS中Output窗口輸出的內容同樣。
總之,VLD是一種高效的診斷、修復C/C++程序內存泄露的方法。
應用舉例
#include "stdafx.h" #ifdef _DEBUG //在Release模式下,不會連接Visual Leak Detector #include "vld.h" #endif int _tmain(int argc, _TCHAR* argv[]) { char* ch1 = new char[100]; char* ch2 = (char*)malloc(200); /* if (ch1 != NULL) { delete[] ch1; ch1 = NULL; } if (ch2 != NULL) { free(ch2); ch1 = NULL; } */ return 0; }
Output輸出:
Visual Leak Detector Version 2.2.3 installed.
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 1 at 0x008CD6F8: 100 bytes ----------
Call Stack:
c:\users \consoleapplication\consoleapplication.cpp (12): ConsoleApplication.exe!wmain + 0x7 bytes
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (533): ConsoleApplication.exe!__tmainCRTStartup + 0x19 bytes
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (377): ConsoleApplication.exe!wmainCRTStartup
0x74EE8543 (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0xE bytes
0x770EAC69 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x85 bytes
0x770EAC3C (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x58 bytes
Data:
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD ........ ........
---------- Block 2 at 0x008CD798: 200 bytes ----------
Call Stack:
c:\users\ \consoleapplication\consoleapplication.cpp (13): ConsoleApplication.exe!wmain + 0xD bytes
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (533): ConsoleApplication.exe!__tmainCRTStartup + 0x19 bytes
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (377): ConsoleApplication.exe!wmainCRTStartup
0x74EE8543 (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0xE bytes
0x770EAC69 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x85 bytes
0x770EAC3C (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x58 bytes
Data:
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD ........ ........
Visual Leak Detector detected 2 memory leaks (372 bytes).
Largest number used: 372 bytes.
Total allocations: 372 bytes.
Visual Leak Detector is now exiting.
The program '[0x262C] ConsoleApplication1.exe' has exited with code 0 (0x0).
輸出的部分主要分爲兩塊
Call Stack部分:
是泄露內存的調用堆棧,其中顯示了泄露資源建立的位置,雙擊即可以定位到相應的代碼部分。
Data部分:
即泄露部分的內存內容。