最近寫一個程序時,出現(xiàn)了內(nèi)存泄漏問題。然后到網(wǎng)上搜索了一下,發(fā)現(xiàn)了一個簡單易用的開源內(nèi)存泄漏檢測工具Visual Leak Detector (VLD) ,在visual c++上工作的很好,其他環(huán)境尚未研究。源代碼、安裝文件可以從codeproject下載,目前最新版本是v1.9b。
先說說這個工具的使用。安裝完畢,在需要調(diào)試的項(xiàng)目中加入把Visual Leak Detector 的Include目錄和LIB目錄添加到項(xiàng)目的路徑中去。再在需要監(jiān)視的cpp文件頭中加入#include <vld.h>,如果是MFC程序,就可以直接在stdafx.h的最后面加上這一句。剩下的就是運(yùn)行調(diào)試程序,在output窗口察看結(jié)果了。
我的錯誤信息如下。
---------- Block 251168 at 0x00FE9998: 16 bytes ----------
Call Stack:
c:\program files\microsoft visual studio .net 2003\vc7\include\xmemory (34): std::_Allocate<char>
c:\program files\microsoft visual studio .net 2003\vc7\include\xmemory (137): std::allocator<char>::allocate
c:\program files\microsoft visual studio .net 2003\vc7\include\xstring (1454): std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Copy
c:\program files\microsoft visual studio .net 2003\vc7\include\xstring (1485): std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Grow
c:\program files\microsoft visual studio .net 2003\vc7\include\xstring (612): std::basic_string<char,std::char_traits<char>,std::allocator<char> >::assign
c:\program files\microsoft visual studio .net 2003\vc7\include\xstring (623): std::basic_string<char,std::char_traits<char>,std::allocator<char> >::assign
c:\program files\microsoft visual studio .net 2003\vc7\include\xstring (473): std::basic_string<char,std::char_traits<char>,std::allocator<char> >::operator=
d:\projects\client\quoteclient\tradetransaction.cpp (2143): CTradeTransaction::AnsReadTodayOrder
d:\projects\client\quoteclient\tradetransaction.cpp (2694): CTradeTransaction::ProcessAllReq
d:\projects\client\quoteclient\tradesocket.cpp (93): CTradeSocket::ReceivePacket
d:\projects\client\quoteclient\tradethread.cpp (146): CTradeThread::RunWorkerInternal
d:\projects\client\quoteclient\tradethread.cpp (97): CTradeThread::WorkerThreadProc
f:\vs70builds\3077\vc\crtbld\crt\src\threadex.c (241): _threadstartex
0x7C80B729 (File and line number not available): GetModuleFileNameA
Data:
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
點(diǎn)擊內(nèi)存泄漏條目可以定位到某一行源代碼,可以看出主要是使用std::string不當(dāng)造成的內(nèi)存泄漏。
進(jìn)一步分析發(fā)現(xiàn)是由于對某個結(jié)構(gòu)體的成員變量std::string誤使用了memset初始化造成的。
struct tag_myStruct
{
std::string id;
int value;
}
總結(jié)一下,在c語言中,結(jié)構(gòu)體的初始化,是可以直接memset(pStruct, 0, sizeof(tag_myStruct));
但在c++中必須小心,比如上面的結(jié)構(gòu)實(shí)際上就是一個類了,習(xí)慣性的用memset就會出錯。為防止這種慣性思維,建議將所有復(fù)雜結(jié)構(gòu)直接用class來申明.然后定義缺省構(gòu)造函數(shù)。否則將來使用時一不小心,就可能造成不測。
補(bǔ)充:盡量不要在C++程序中使用C風(fēng)格的代碼。但這個是需要一些時間來調(diào)整的。