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

隨筆-380  評論-37  文章-0  trackbacks-0

原帖:http://blog.csdn.net/i_like_cpp/archive/2007/06/28/1669962.aspx
作者:許式偉 2006年11月某日

內(nèi)存管理是C++程序員的痛。我的《內(nèi)存管理變革》系列就是試圖討論更為有效的內(nèi)存管理方式,以杜絕(或減少)內(nèi)存泄漏,減輕C++程序員的負(fù)擔(dān)。由于工作忙的緣故,這個系列目前未完,暫停。
?
這篇短文我想換個方式,討論一下如何以最快的速度找到內(nèi)存泄漏。
?
確認(rèn)是否存在內(nèi)存泄漏
我們知道,MFC程序如果檢測到存在內(nèi)存泄漏,退出程序的時候會在調(diào)試窗口提醒內(nèi)存泄漏。例如:

class CMyApp : public CWinApp
{
public:
?? BOOL InitApplication()
?? {
?????? int* leak = new int[10];
?????? return TRUE;
?? }
};
產(chǎn)生的內(nèi)存泄漏報告大體如下:

Detected memory leaks!
Dumping objects ->
c:\work\test.cpp(186) : {52} normal block at 0x003C4410, 40 bytes long.
?Data: <??????????????? > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
這挺好。問題是,如果我們不喜歡MFC,那么難道就沒有辦法?或者自己做?

呵呵,這不需要。其實,MFC也沒有自己做。內(nèi)存泄漏檢測的工作是VC++的C運(yùn)行庫做的。也就是說,只要你是VC++程序員,都可以很方便地檢測內(nèi)存泄漏。我們還是給個樣例:

#include <crtdbg.h>

inline void EnableMemLeakCheck()
{
?? _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
}

void main()
{
?? EnableMemLeakCheck();
?? int* leak = new int[10];
}
?運(yùn)行(提醒:不要按Ctrl+F5,按F5),你將發(fā)現(xiàn),產(chǎn)生的內(nèi)存泄漏報告與MFC類似,但有細(xì)節(jié)不同,如下:

Detected memory leaks!
Dumping objects ->
{52} normal block at 0x003C4410, 40 bytes long.
?Data: <??????????????? > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
為什么呢?看下面。

定位內(nèi)存泄漏由于哪一句話引起的
你已經(jīng)發(fā)現(xiàn)程序存在內(nèi)存泄漏。現(xiàn)在的問題是,我們要找泄漏的根源。

一般我們首先確定內(nèi)存泄漏是由于哪一句引起。在MFC中,這一點(diǎn)很容易。你雙擊內(nèi)存泄漏報告的文字,或者在Debug窗口中按F4,IDE就幫你定位到申請該內(nèi)存塊的地方。對于上例,也就是這一句:

?? int* leak = new int[10];

這多多少少對你分析內(nèi)存泄漏有點(diǎn)幫助。特別地,如果這個new僅對應(yīng)一條delete(或者你把delete漏寫),這將很快可以確認(rèn)問題的癥結(jié)。

我們前面已經(jīng)看到,不使用MFC的時候,生成的內(nèi)存泄漏報告與MFC不同,而且你立刻發(fā)現(xiàn)按F4不靈。那么難道MFC做了什么手腳?

其實不是,我們來模擬下MFC做的事情。看下例:

inline void EnableMemLeakCheck()
{
?? _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
}

#ifdef _DEBUG
#define new?? new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif

void main()
{
?? EnableMemLeakCheck();
?? int* leak = new int[10];
}

再運(yùn)行這個樣例,你驚喜地發(fā)現(xiàn),現(xiàn)在內(nèi)存泄漏報告和MFC沒有任何分別了。

快速找到內(nèi)存泄漏
單確定了內(nèi)存泄漏發(fā)生在哪一行,有時候并不足夠。特別是同一個new對應(yīng)有多處釋放的情形。在實際的工程中,以下兩種情況很典型:

創(chuàng)建對象的地方是一個類工廠(ClassFactory)模式。很多甚至全部類實例由同一個new創(chuàng)建。對于此,定位到了new出對象的所在行基本沒有多大幫助。
?
COM對象。我們知道COM對象采用Reference Count維護(hù)生命周期。也就是說,對象new的地方只有一個,但是Release的地方很多,你要一個個排除。
那么,有什么好辦法,可以迅速定位內(nèi)存泄漏?

答:有。

在內(nèi)存泄漏情況復(fù)雜的時候,你可以用以下方法定位內(nèi)存泄漏。這是我個人認(rèn)為通用的內(nèi)存泄漏追蹤方法中最有效的手段。

我們再回頭看看crtdbg生成的內(nèi)存泄漏報告:

Detected memory leaks!
Dumping objects ->
c:\work\test.cpp(186) : {52} normal block at 0x003C4410, 40 bytes long.
?Data: <??????????????? > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
除了產(chǎn)生該內(nèi)存泄漏的內(nèi)存分配語句所在的文件名、行號為,我們注意到有一個比較陌生的信息:{52}。這個整數(shù)值代表了什么意思呢?

其實,它代表了第幾次內(nèi)存分配操作。象這個例子,{52}代表了第52次內(nèi)存分配操作發(fā)生了泄漏。你可能要說,我只new過一次,怎么會是第52次?這很容易理解,其他的內(nèi)存申請操作在C的初始化過程調(diào)用的唄。:)

有沒有可能,我們讓程序運(yùn)行到第52次內(nèi)存分配操作的時候,自動停下來,進(jìn)入調(diào)試狀態(tài)?所幸,crtdbg確實提供了這樣的函數(shù):即 long _CrtSetBreakAlloc(long nAllocID)。我們加上它:

inline void EnableMemLeakCheck()
{
?? _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
}

#ifdef _DEBUG
#define new?? new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif

void main()
{
?? EnableMemLeakCheck();
?? _CrtSetBreakAlloc(52);
?? int* leak = new int[10];
}
你發(fā)現(xiàn),程序運(yùn)行到 int* leak = new int[10]; 一句時,自動停下來進(jìn)入調(diào)試狀態(tài)。細(xì)細(xì)體會一下,你可以發(fā)現(xiàn),這種方式你獲得的信息遠(yuǎn)比在程序退出時獲得文件名及行號有價值得多。因為報告泄漏文件名及行號,你獲得的只是靜態(tài)的信息,然而_CrtSetBreakAlloc則是把整個現(xiàn)場恢復(fù),你可以通過對函數(shù)調(diào)用棧分析(我發(fā)現(xiàn)很多人不習(xí)慣看函數(shù)調(diào)用棧,如果你屬于這種情況,我強(qiáng)烈推薦你去補(bǔ)上這一課,因為它太重要了)以及其他在線調(diào)試技巧,來分析產(chǎn)生內(nèi)存泄漏的原因。通常情況下,這種分析方法可以在5分鐘內(nèi)找到肇事者。

當(dāng)然,_CrtSetBreakAlloc要求你的程序執(zhí)行過程是可還原的(多次執(zhí)行過程的內(nèi)存分配順序不會發(fā)生變化)。這個假設(shè)在多數(shù)情況下成立。不過,在多線程的情況下,這一點(diǎn)有時難以保證。

?


附加說明:
對“內(nèi)存管理”相關(guān)的技術(shù)感興趣?這里可以看到我的所有關(guān)于內(nèi)存管理的文章。

?

本文來自CSDN博客,轉(zhuǎn)載請標(biāo)明出處: http://blog.csdn.net/i_like_cpp/archive/2007/06/28/1669962.aspx

posted on 2010-01-21 23:14 小王 閱讀(851) 評論(0)  編輯 收藏 引用 所屬分類: c++ 程序設(shè)計基礎(chǔ)
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久久久国内| 蜜臀a∨国产成人精品 | 亚洲日本va午夜在线电影| 国产日韩欧美91| 国产精品二区二区三区| 欧美偷拍一区二区| 国产精品久久久久aaaa九色| 国产伦精品一区二区三区视频孕妇 | 亚洲欧美激情在线视频| 亚洲一区图片| 久久国产精品一区二区三区| 另类天堂av| 欧美四级在线观看| 国产精品一区毛片| 亚洲国产三级| 亚洲欧美成人一区二区在线电影| 久久精品成人欧美大片古装| 欧美插天视频在线播放| 99国产精品99久久久久久粉嫩| 亚洲欧美日韩国产综合| 久久综合图片| 国产精品蜜臀在线观看| 欲香欲色天天天综合和网| 亚洲少妇自拍| 久久性色av| 一本色道精品久久一区二区三区| 久久国产主播精品| 欧美三级电影大全| 亚洲电影第1页| 午夜亚洲伦理| 亚洲国产天堂网精品网站| 一区二区三区精品国产| 久久成人在线| 国产精品久久久久久久久久久久久| 狠狠色综合色综合网络| 亚洲无亚洲人成网站77777 | 99视频超级精品| 久久亚洲欧洲| 亚洲女人天堂成人av在线| 美女久久一区| 黄色欧美日韩| 亚洲一区二区在| 亚洲福利国产精品| 久久国产精品一区二区| 久久精品麻豆| 亚洲精品国产精品国自产观看浪潮| 亚洲欧美999| 亚洲第一福利在线观看| 午夜在线观看免费一区| 欧美午夜精品久久久| 亚洲三级毛片| 欧美韩国一区| 美女主播一区| 亚洲高清免费在线| 美女露胸一区二区三区| 欧美在线免费观看视频| 国产精品日韩精品| 亚洲欧美日韩系列| 一道本一区二区| 欧美日韩亚洲一区二区三区在线 | 欧美剧在线观看| 亚洲国产精品一区二区尤物区 | 久久亚洲高清| 欧美在线观看视频一区二区| 国产欧美一区二区色老头 | 久久久www成人免费无遮挡大片| 国产精品丝袜xxxxxxx| 欧美亚洲免费电影| 欧美尤物巨大精品爽| 黄色综合网站| 欧美高清视频一区| 欧美巨乳在线观看| 亚洲女与黑人做爰| 欧美一区二区三区日韩视频| 国产中文一区二区| 欧美国产第一页| 欧美精品久久天天躁| 中文有码久久| 午夜精品影院| 亚洲国产黄色片| 亚洲激情综合| 欧美午夜欧美| 久久国产色av| 六月天综合网| 亚洲一级在线观看| 欧美在线视频日韩| 亚洲人成网站影音先锋播放| 亚洲精品偷拍| 国产精品爽爽ⅴa在线观看| 久久手机免费观看| 欧美日韩高清区| 欧美自拍偷拍| 免费一级欧美片在线观看| 亚洲精品美女在线| 亚洲在线中文字幕| ●精品国产综合乱码久久久久| 亚洲国产欧美一区二区三区丁香婷| 亚洲激情电影中文字幕| 欧美日韩成人一区二区三区| 欧美一区二区精品在线| 久久亚洲精品一区| 亚洲一二区在线| 久久亚洲影音av资源网| 亚洲影视中文字幕| 老司机免费视频一区二区三区| 一区二区精品| 久久五月天婷婷| 午夜精品久久久久影视| 欧美α欧美αv大片| 欧美在线观看你懂的| 欧美精品aa| 男女精品视频| 国产一区二区三区电影在线观看| 亚洲精品国产欧美| 亚洲高清毛片| 久久se精品一区精品二区| 亚洲性xxxx| 欧美www在线| 蜜臀久久99精品久久久久久9| 国产精品美女久久久久久2018| 亚洲国产婷婷香蕉久久久久久99| 国产一区二区三区四区老人| 亚洲午夜精品在线| 亚洲午夜伦理| 欧美午夜精品久久久久免费视 | 亚洲国产网站| 91久久一区二区| 久久久久国产精品麻豆ai换脸| 先锋影音一区二区三区| 国产精品成人免费精品自在线观看 | 亚洲激情一区二区| 久久精品在线免费观看| 久久aⅴ乱码一区二区三区| 国产精品多人| 一区二区高清在线观看| 亚洲一区二区免费在线| 欧美无乱码久久久免费午夜一区| 91久久夜色精品国产网站| 亚洲欧洲综合| 欧美国产综合| 亚洲人成毛片在线播放| 99riav国产精品| 欧美日本一道本| 亚洲久久成人| 亚洲欧美欧美一区二区三区| 国产精品大片wwwwww| 亚洲天堂av综合网| 香蕉久久一区二区不卡无毒影院| 国产精品日韩| 久久精品国产96久久久香蕉| 久久蜜桃精品| 亚洲第一精品夜夜躁人人躁| 久久一区二区三区超碰国产精品| 免费看成人av| 99国产精品久久久| 欧美三区不卡| 欧美在线1区| 欧美激情91| 亚洲综合成人婷婷小说| 国产日韩在线一区二区三区| 免费观看日韩| 亚洲美女视频| 国产精品久久午夜夜伦鲁鲁| 小黄鸭精品aⅴ导航网站入口| 久久夜精品va视频免费观看| 亚洲精品乱码久久久久久蜜桃91| 欧美日韩麻豆| 欧美一区二区三区视频| 欧美激情一区在线| 午夜精彩视频在线观看不卡| 伊人春色精品| 国产精品第十页| 麻豆成人在线播放| 亚洲一区二区网站| 亚洲第一偷拍| 久久精品视频免费| 亚洲麻豆av| 好吊日精品视频| 欧美日韩视频不卡| 久久精品视频一| 一区二区久久久久久| 蜜桃视频一区| 亚洲欧美视频一区| 亚洲三级观看| 韩日精品视频| 欧美性大战久久久久久久| 久久久久九九九九| 亚洲永久精品国产| 亚洲精品乱码久久久久久黑人 | 欧美在线免费观看| 日韩午夜剧场| 亚洲第一免费播放区| 久久精品人人| 先锋资源久久| 夜夜嗨av一区二区三区免费区| 国产亚洲精品激情久久| 国产精品国产成人国产三级| 欧美激情一区二区三区在线视频| 久久精品亚洲精品| 欧美中文字幕久久|