我已經使用了可視化泄漏檢測器,結果相當好。這是小而整潔,可以內置到您的項目(假設你有一個正在運行的調試配置)在幾秒鐘的事:
https://vld.codeplex.com/
如果設置正確(可使用安裝完成),那麼你只需要
#include <vld.h>
在每個模塊的.cpp文件的一個 - 這是它的頭部會做鏈接給你。你不必把它放在任何地方。該工具在內部使用CrtDbg,因此您必須運行一個調試版本才能運行。
它在每次運行後給出調試器或文本輸出(如果使用配置文件進行配置),即使不通過調試器運行。這不是最強大的工具,但這些通常成本一些硬幣;)
EDIT:有一種可能性,通過包括頭之前定義VLD_FORCE_ENABLE
使VLD也在非調試配置。但結果可能會隨着時間而減弱。
編輯:我試過了VLD的全新安裝。請注意,對於VS2013編譯器,必須使用v2.4rc2版本(或更高版本的v2.3)。版本v2.3只能在VS2010編譯器之前運行。
安裝完成後,我創建了一個新項目,並設置我的include和library目錄以包含各自的VLD文件夾。從那以後,我用下面的代碼來測試memleak單身的報告(注意,此代碼沒有任何意義,它只是證明了一點):
#include <iostream>
#include <string>
#include <sstream>
#include <map>
// Uncomment this, if you want VLD to work in non-debug configurations
//#define VLD_FORCE_ENABLE
#include <vld.h>
class FooSingleton {
private:
std::map<std::string, std::string*>
_map;
FooSingleton() {
}
public:
static FooSingleton* getInstance(void) {
/* THIS WOULD CAUSE LEAKS TO BE DETECTED
SINCE THE DESTRUCTOR WILL NEVER BE CALLEd
AND THE MAP IS NOT CLEARED.
*/
// FooSingleton* instance = new FooSingleton;
// return instance;
static FooSingleton instance;
return &instance;
}
void addString(const std::string& val) {
_map.insert(std::make_pair(val, new std::string(val)));
}
~FooSingleton(void) {
auto it = _map.begin();
auto ite = _map.end();
for(; it != ite; ++it) {
delete it->second;
}
}
};
int main(int argc, char** argv) {
FooSingleton* fs = FooSingleton::getInstance();
for(int i = 0; i < 100; ++i) {
std::stringstream ss;
ss << i << "nth string.";
fs->addString(ss.str());
}
return 0;
}
有了這個代碼,該VLD不會報告任何泄漏,因爲getInstance()
中的靜態自動變量將在退出時被破壞,並且地圖中的元素將被刪除。儘管如此,即使它是單身人士,也要這樣做,否則就會報告泄密事件。但是,在這種情況下:
Visual Leak Detector Version 2.3 installed.
Aggregating duplicate leaks.
Outputting the report to the debugger and to D:\dev\projects\tmp\memleak\memleak\memory_leak_report.txt
No memory leaks detected. Visual Leak Detector is now exiting.
如果getInstance()
代碼改爲註釋版本,那麼單是從來沒有清理及以下泄漏(其中包括)報道:
---------- Block 11 at 0x008E5928: 52 bytes ----------
Leak Hash: 0x973608A9 Count: 100
Call Stack:
c:\program files (x86)\microsoft visual studio 10.0\vc\include\xmemory (36): memleak.exe!std::_Allocate<std::_Tree_nod<std::_Tmap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,std::less<std::basic_string<char,std::char_traits<char>,std::alloca + 0x15 bytes
c:\program files (x86)\microsoft visual studio 10.0\vc\include\xmemory (187): memleak.exe!std::allocator<std::_Tree_nod<std::_Tmap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,std::less<std::basic_string<char,std::char_traits<char>,std::alloca + 0xB bytes
c:\program files (x86)\microsoft visual studio 10.0\vc\include\xtree (560): memleak.exe!std::_Tree_val<std::_Tmap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,s + 0xD bytes
c:\program files (x86)\microsoft visual studio 10.0\vc\include\xtree (588): memleak.exe!std::_Tree_val<std::_Tmap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,s + 0x8 bytes
c:\program files (x86)\microsoft visual studio 10.0\vc\include\xtree (756): memleak.exe!std::_Tree<std::_Tmap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std:: + 0x17 bytes
d:\dev\projects\tmp\memleak\memleak\main.cpp (33): memleak.exe!FooSingleton::addString + 0xA9 bytes
d:\dev\projects\tmp\memleak\memleak\main.cpp (51): memleak.exe!main + 0x37 bytes
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (555): memleak.exe!__tmainCRTStartup + 0x19 bytes
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (371): memleak.exe!mainCRTStartup
0x76BF919F (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0xE bytes
0x7739A22B (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x84 bytes
0x7739A201 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x5A bytes
Data:
C0 53 8E 00 30 67 8E 00 C0 53 8E 00 98 58 8E 00 .S..0g.. .S...X..
30 6E 74 68 20 73 74 72 69 6E 67 2E 00 CD CD CD 0nth.str ing.....
0C 00 00 00 0F 00 00 00 CD CD CD CD 48 56 8E 00 ........ ....HV..
01 00 CD CD
你可以清楚地看到這個代碼塊的Count: 100
,這是正確的。
我還編輯我vld.ini
文件的安裝目錄下有以下設置爲啓用:
AggregateDuplicates = yes
ReportTo = both
這些確保一)所有重複的泄漏被擠壓在一起,一個報告與泄漏數(如上所述,否則會有100個條目),另一個是報告文件被轉儲到應用程序的目錄中。
因此,對於單身人士,只要你使用你正在使用的靜態自動變量方法並在析構函數中進行清理,它就可以正常工作。
編輯:此外,儀器可以在特定的代碼段被禁用。如果上面的代碼將被修改如下:
void addString(const std::string& val) {
VLDDisable();
_map.insert(std::make_pair(val, new std::string(val)));
VLDEnable();
}
泄漏將永遠被異形,而不是跟蹤。
有些工具不是免費的,但提供了功能完整的試用版。所以你不必花錢來檢查泄漏。 – 2014-11-23 22:01:36
不太確定它是否正是你所需要的,但是valgrind http://valgrind.org/docs/manual/mc-manual.html提供了檢測內存泄漏的工具。 – Vincent 2014-11-24 20:22:54