青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

春暖花開
雪化了,花開了,春天來了
posts - 149,comments - 125,trackbacks - 0
http://www.vczx.com/article/show.php?id=68

檢測(cè)內(nèi)存泄漏:
檢測(cè)內(nèi)存泄漏的關(guān)鍵是要能截獲住對(duì)分配內(nèi)存和釋放內(nèi)存的函數(shù)的調(diào)用。截獲住這兩個(gè)函數(shù),我們就能跟蹤每一塊內(nèi)存的生命周期,比如,每當(dāng)成功的分配一塊內(nèi)存后,就把它的指針加入一個(gè)全局的list中;每當(dāng)釋放一塊內(nèi)存,再把它的指針從list中刪除。這樣,當(dāng)程序結(jié)束的時(shí)候,list中剩余的指針就是指向那些沒有被釋放的內(nèi)存。這里只是簡(jiǎn)單的描述了檢測(cè)內(nèi)存泄漏的基本原理,詳細(xì)的算法可以參見Steve Maguire的<<Writing Solid Code>>。
如果要檢測(cè)堆內(nèi)存的泄漏,那么需要截獲住malloc/realloc/free和new/delete就可以了(其實(shí)new/delete最終也是用malloc/free的,所以只要截獲前面一組即可)。對(duì)于其他的泄漏,可以采用類似的方法,截獲住相應(yīng)的分配和釋放函數(shù)。比如,要檢測(cè)BSTR的泄漏,就需要截獲SysAllocString/SysFreeString;要檢測(cè)HMENU的泄漏,就需要截獲CreateMenu/ DestroyMenu。(有的資源的分配函數(shù)有多個(gè),釋放函數(shù)只有一個(gè),比如,SysAllocStringLen也可以用來分配BSTR,這時(shí)就需要截獲多個(gè)分配函數(shù))
在Windows平臺(tái)下,檢測(cè)內(nèi)存泄漏的工具常用的一般有三種,MS C-Runtime Library內(nèi)建的檢測(cè)功能;外掛式的檢測(cè)工具,諸如,Purify,BoundsChecker等;利用Windows NT自帶的Performance Monitor。這三種工具各有優(yōu)缺點(diǎn),MS C-Runtime Library雖然功能上較之外掛式的工具要弱,但是它是免費(fèi)的;Performance Monitor雖然無法標(biāo)示出發(fā)生問題的代碼,但是它能檢測(cè)出隱式的內(nèi)存泄漏的存在,這是其他兩類工具無能為力的地方。
以下我們?cè)敿?xì)討論這三種檢測(cè)工具:
VC下內(nèi)存泄漏的檢測(cè)方法
用MFC開發(fā)的應(yīng)用程序,在DEBUG版模式下編譯后,都會(huì)自動(dòng)加入內(nèi)存泄漏的檢測(cè)代碼。在程序結(jié)束后,如果發(fā)生了內(nèi)存泄漏,在Debug窗口中會(huì)顯示出所有發(fā)生泄漏的內(nèi)存塊的信息,以下兩行顯示了一塊被泄漏的內(nèi)存塊的信息:
E:\TestMemLeak\TestDlg.cpp(70)     : {59} normal block at 0x00881710, 200 bytes long.
Data: <abcdefghijklmnop>     61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70
第一行顯示該內(nèi)存塊由TestDlg.cpp文件,第70行代碼分配,地址在0x00881710,大小為200字節(jié),{59}是指調(diào)用內(nèi)存分配函數(shù)的Request Order,關(guān)于它的詳細(xì)信息可以參見MSDN中_CrtSetBreakAlloc()的幫助。第二行顯示該內(nèi)存塊前16個(gè)字節(jié)的內(nèi)容,尖括號(hào)內(nèi)是以ASCII方式顯示,接著的是以16進(jìn)制方式顯示。
一般大家都誤以為這些內(nèi)存泄漏的檢測(cè)功能是由MFC提供的,其實(shí)不然。MFC只是封裝和利用了MS C-Runtime Library的Debug Function。非MFC程序也可以利用MS C-Runtime Library的Debug Function加入內(nèi)存泄漏的檢測(cè)功能。MS C-Runtime Library在實(shí)現(xiàn)malloc/free,strdup等函數(shù)時(shí)已經(jīng)內(nèi)建了內(nèi)存泄漏的檢測(cè)功能。
注意觀察一下由MFC Application Wizard生成的項(xiàng)目,在每一個(gè)cpp文件的頭部都有這樣一段宏定義:
#ifdef     _DEBUG
#define     new DEBUG_NEW
#undef     THIS_FILE
static     char THIS_FILE[] = __FILE__;
#endif
有了這樣的定義,在編譯DEBUG版時(shí),出現(xiàn)在這個(gè)cpp文件中的所有new都被替換成DEBUG_NEW了。那么DEBUG_NEW是什么呢?DEBUG_NEW也是一個(gè)宏,以下摘自afx.h,1632行
#define     DEBUG_NEW new(THIS_FILE, __LINE__)
所以如果有這樣一行代碼:
char*     p = new char[200];
經(jīng)過宏替換就變成了:
char*     p = new( THIS_FILE, __LINE__)char[200];
根據(jù)C++的標(biāo)準(zhǔn),對(duì)于以上的new的使用方法,編譯器會(huì)去找這樣定義的operator new:
void*     operator new(size_t, LPCSTR, int)
我們?cè)赼fxmem.cpp 63行找到了一個(gè)這樣的operator new 的實(shí)現(xiàn)
void*     AFX_CDECL operator new(size_t nSize, LPCSTR lpszFileName, int nLine)
{
    return     ::operator new(nSize, _NORMAL_BLOCK, lpszFileName, nLine);
}
void*     __cdecl operator new(size_t nSize, int nType, LPCSTR lpszFileName, int     nLine)
{
    …
           pResult = _malloc_dbg(nSize, nType,     lpszFileName, nLine);
           if (pResult != NULL)
               return pResult;
    …
}
第二個(gè)operator new函數(shù)比較長(zhǎng),為了簡(jiǎn)單期間,我只摘錄了部分。很顯然最后的內(nèi)存分配還是通過_malloc_dbg函數(shù)實(shí)現(xiàn)的,這個(gè)函數(shù)屬于MS C-Runtime Library 的Debug Function。這個(gè)函數(shù)不但要求傳入內(nèi)存的大小,另外還有文件名和行號(hào)兩個(gè)參數(shù)。文件名和行號(hào)就是用來記錄此次分配是由哪一段代碼造成的。如果這塊內(nèi)存在程序結(jié)束之前沒有被釋放,那么這些信息就會(huì)輸出到Debug窗口里。
這里順便提一下THIS_FILE,__FILE和__LINE__。__FILE__和__LINE__都是編譯器定義的宏。當(dāng)碰到__FILE__時(shí),編譯器會(huì)把__FILE__替換成一個(gè)字符串,這個(gè)字符串就是當(dāng)前在編譯的文件的路徑名。當(dāng)碰到__LINE__時(shí),編譯器會(huì)把__LINE__替換成一個(gè)數(shù)字,這個(gè)數(shù)字就是當(dāng)前這行代碼的行號(hào)。在DEBUG_NEW的定義中沒有直接使用__FILE__,而是用了THIS_FILE,其目的是為了減小目標(biāo)文件的大小。假設(shè)在某個(gè)cpp文件中有100處使用了new,如果直接使用__FILE__,那編譯器會(huì)產(chǎn)生100個(gè)常量字符串,這100個(gè)字符串都是這個(gè)cpp文件的路徑名,顯然十分冗余。如果使用THIS_FILE,編譯器只會(huì)產(chǎn)生一個(gè)常量字符串,那100處new的調(diào)用使用的都是指向常量字符串的指針。
再次觀察一下由MFC Application Wizard生成的項(xiàng)目,我們會(huì)發(fā)現(xiàn)在cpp文件中只對(duì)new做了映射,如果你在程序中直接使用malloc函數(shù)分配內(nèi)存,調(diào)用malloc的文件名和行號(hào)是不會(huì)被記錄下來的。如果這塊內(nèi)存發(fā)生了泄漏,MS C-Runtime Library仍然能檢測(cè)到,但是當(dāng)輸出這塊內(nèi)存塊的信息,不會(huì)包含分配它的的文件名和行號(hào)。
要在非MFC程序中打開內(nèi)存泄漏的檢測(cè)功能非常容易,你只要在程序的入口處加入以下幾行代碼:
int     tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
tmpFlag     |= _CRTDBG_LEAK_CHECK_DF;
_CrtSetDbgFlag(     tmpFlag );
這樣,在程序結(jié)束的時(shí)候,也就是winmain,main或dllmain函數(shù)返回之后,如果還有內(nèi)存塊沒有釋放,它們的信息會(huì)被打印到Debug窗口里。
如果你試著創(chuàng)建了一個(gè)非MFC應(yīng)用程序,而且在程序的入口處加入了以上代碼,并且故意在程序中不釋放某些內(nèi)存塊,你會(huì)在Debug窗口里看到以下的信息:
{47}     normal block at 0x00C91C90, 200 bytes long.
Data: <            > 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
內(nèi)存泄漏的確檢測(cè)到了,但是和上面MFC程序的例子相比,缺少了文件名和行號(hào)。對(duì)于一個(gè)比較大的程序,沒有這些信息,解決問題將變得十分困難。
為了能夠知道泄漏的內(nèi)存塊是在哪里分配的,你需要實(shí)現(xiàn)類似MFC的映射功能,把new,maolloc等函數(shù)映射到_malloc_dbg函數(shù)上。這里我不再贅述,你可以參考MFC的源代碼。
由于Debug Function實(shí)現(xiàn)在MS C-RuntimeLibrary中,所以它只能檢測(cè)到堆內(nèi)存的泄漏,而且只限于malloc,realloc或strdup等分配的內(nèi)存,而那些系統(tǒng)資源,比如HANDLE,GDI Object,或是不通過C-Runtime Library分配的內(nèi)存,比如VARIANT,BSTR的泄漏,它是無法檢測(cè)到的,這是這種檢測(cè)法的一個(gè)重大的局限性。另外,為了能記錄內(nèi)存塊是在哪里分配的,源代碼必須相應(yīng)的配合,這在調(diào)試一些老的程序非常麻煩,畢竟修改源代碼不是一件省心的事,這是這種檢測(cè)法的另一個(gè)局限性。
對(duì)于開發(fā)一個(gè)大型的程序,MS C-Runtime Library提供的檢測(cè)功能是遠(yuǎn)遠(yuǎn)不夠的。接下來我們就看看外掛式的檢測(cè)工具。我用的比較多的是BoundsChecker,一則因?yàn)樗墓δ鼙容^全面,更重要的是它的穩(wěn)定性。這類工具如果不穩(wěn)定,反而會(huì)忙里添亂。到底是出自鼎鼎大名的NuMega,我用下來基本上沒有什么大問題。
posted on 2008-11-02 10:54 Sandy 閱讀(244) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C++
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产一区视频网站| 久久免费精品视频| 久久亚洲一区二区三区四区| 亚洲天堂网站在线观看视频| 美日韩丰满少妇在线观看| 久久精品人人做人人爽电影蜜月| 欧美精品久久一区| 欧美电影免费网站| 激情成人在线视频| 亚洲无限乱码一二三四麻| 日韩一级黄色av| 欧美黄色日本| 欧美激情按摩在线| 在线观看一区二区精品视频| 欧美在线免费| 久久中文字幕一区二区三区| 国产一区二区高清视频| 午夜精品理论片| 久久aⅴ国产紧身牛仔裤| 国产精品入口66mio| 亚洲视频香蕉人妖| 亚洲欧美日韩天堂| 国产精品入口尤物| 亚洲小视频在线| 欧美一级视频精品观看| 国产精品乱子久久久久| 午夜精品999| 欧美在线1区| 国产午夜亚洲精品不卡| 久久精品日韩| 你懂的国产精品| 亚洲欧洲一区二区三区| 欧美国产精品劲爆| 99国产精品国产精品久久| 亚洲四色影视在线观看| 国产精品美女久久久久久久| 午夜精品福利在线| 久久久久国产精品人| 伊人成年综合电影网| 麻豆成人av| 日韩视频一区二区| 香蕉久久一区二区不卡无毒影院 | 午夜精品福利在线| 久久精品亚洲一区| 影音先锋中文字幕一区二区| 欧美wwwwww| av成人免费在线| 久久精品国产精品亚洲综合| 伊人久久婷婷| 欧美美女喷水视频| 午夜在线成人av| 亚洲丰满在线| 亚洲图片欧美日产| 国内精品免费在线观看| 欧美激情自拍| 性18欧美另类| 亚洲第一福利在线观看| 亚洲一区二区3| 影音先锋久久精品| 欧美日韩精品三区| 久久精品色图| 99视频精品| 免费视频一区| 亚洲欧美在线免费观看| 在线观看亚洲精品视频| 国产精品海角社区在线观看| 六月婷婷久久| 亚洲欧美日韩精品久久亚洲区| 欧美激情女人20p| 欧美一级网站| 99热在这里有精品免费| 国产一区美女| 欧美日韩综合视频| 免费久久精品视频| 亚洲欧美不卡| 亚洲免费观看视频| 欧美激情1区2区| 久久久久免费观看| 亚洲自拍偷拍视频| 亚洲精品一区中文| 亚洲成人在线免费| 国产区精品在线观看| 欧美日韩亚洲91| 蜜臀av性久久久久蜜臀aⅴ四虎| 亚洲一区视频在线观看视频| 91久久精品一区二区别| 蜜桃久久av一区| 久久精品视频va| 亚洲欧美日韩综合一区| 99热免费精品在线观看| 在线观看欧美日韩| 激情欧美日韩一区| 国内视频一区| 国产视频一区欧美| 国产伦精品一区二区三区免费迷| 欧美日韩一区二区免费在线观看 | 欧美肥婆bbw| 久久久久久网址| 久久精品99国产精品酒店日本| 亚洲色图制服丝袜| 在线亚洲欧美| 亚洲天堂成人| 亚洲一级黄色| 亚洲欧美国产另类| 性做久久久久久久免费看| 亚洲女同同性videoxma| 亚洲视频在线看| 亚洲午夜精品视频| 亚洲在线一区二区| 亚洲欧美日韩综合| 亚洲欧美资源在线| 欧美一级视频免费在线观看| 欧美自拍偷拍午夜视频| 久久激情婷婷| 两个人的视频www国产精品| 久久亚洲精品伦理| 欧美福利在线| 国产精品二区影院| 国产精品无码永久免费888| 国产日韩亚洲欧美综合| 极品尤物av久久免费看| 一区视频在线看| 亚洲黄色有码视频| 夜夜嗨av一区二区三区免费区| 一区二区三区www| 午夜在线一区二区| 久久亚洲不卡| 亚洲国产成人不卡| 亚洲深夜福利视频| 欧美一区二区三区视频在线观看| 久久久噜噜噜久久狠狠50岁| 欧美第一黄色网| 国产精品福利av| 国产综合欧美| 日韩一级黄色av| 午夜一区在线| 亚洲成人在线视频播放 | 好看不卡的中文字幕| 亚洲国产精品久久久久秋霞蜜臀| 亚洲精品综合| 午夜精品成人在线| 理论片一区二区在线| 91久久精品www人人做人人爽| 亚洲午夜小视频| 久久综合网络一区二区| 欧美视频免费在线| 有码中文亚洲精品| 这里只有精品在线播放| 久久精品五月| 日韩亚洲精品电影| 久久久久久久性| 欧美肉体xxxx裸体137大胆| 国产日韩精品视频一区| 亚洲精品国久久99热| 久久本道综合色狠狠五月| 亚洲经典三级| 久久精品99久久香蕉国产色戒| 欧美理论大片| 在线精品亚洲一区二区| 亚洲综合色自拍一区| 欧美激情视频一区二区三区在线播放| 一区二区三区四区五区视频 | 美日韩精品免费观看视频| 欧美日韩一区二区三区四区五区 | 亚洲美女黄色| 久久亚洲综合色一区二区三区| 国产精品有限公司| 一区二区三区免费在线观看| 免费永久网站黄欧美| 亚洲男人av电影| 欧美三区美女| 99热在这里有精品免费| 欧美成人情趣视频| 久久久久久成人| 国产真实乱偷精品视频免| 亚洲欧美日韩精品久久亚洲区 | 亚洲福利视频三区| 久久精品人人爽| 国产美女精品在线| 亚洲综合精品四区| 一本色道久久综合亚洲精品高清 | 欧美巨乳波霸| 亚洲精品乱码久久久久久按摩观 | 久久综合狠狠| 久久国产精彩视频| 国产性色一区二区| 欧美中日韩免费视频| 亚洲欧美国产三级| 国产精品网红福利| 欧美一区二区三区在线免费观看 | 欧美午夜在线视频| 亚洲视频精选| 在线视频欧美日韩精品| 欧美四级伦理在线| 亚洲欧美在线一区| 午夜国产精品视频免费体验区| 国产精品欧美激情| 久久精品国产久精国产爱| 欧美一级片一区| 一色屋精品视频免费看|