




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、C 語(yǔ)言中內(nèi)存泄漏的檢測(cè)方法介紹 關(guān)鍵字:C語(yǔ)言首先我們需要知道程序有沒(méi)有內(nèi)存泄露,然后定位到底是哪行代碼出現(xiàn)內(nèi)存泄露了,這 樣才能將其修復(fù)。最簡(jiǎn)單的方法當(dāng)然是借助于專業(yè)的檢測(cè)工具,比較有名如BoundsCheck,功能非常強(qiáng)大, 相信做C+開(kāi)發(fā)的人都離不開(kāi)它。此外就是不使用任何工具,而是自己來(lái)實(shí)現(xiàn)對(duì)內(nèi)存泄露的 監(jiān)控,分如下兩種情況:一。在 MFC 中檢測(cè)內(nèi)存泄漏假如是用MFC的程序的話,很簡(jiǎn)單。默認(rèn)的就有內(nèi)存泄露檢測(cè)的功能。 我們用VS2005生成了一個(gè)MFC的對(duì)話框的程序,發(fā)現(xiàn)他可以自動(dòng)的檢測(cè)內(nèi)存泄露。 不用我們做任何特殊的操作。仔細(xì)觀察,發(fā)現(xiàn)在每個(gè) CPP 文件中,都有下面的代碼:#if
2、def _DEBUG#define new DEBUG_NEW#endifDEBUG_NEW 這個(gè)宏定義在 afx.h 文件中,就是它幫助我們定位內(nèi)存泄漏。 在含有以上代碼的 cpp 文件中分配內(nèi)存后假如沒(méi)有刪除,那么停止程序的時(shí)候, VisualStudio的Output窗口就會(huì)顯示如下的信息了:Detected memory leaks!Dumping objects -d:codemfctestmfctest.cpp(80) : 157 normal block at 0 x003AF170, 4 bytes long. Data: 00 00 00 00Object dump comp
3、lete.在Output窗口雙擊粗體字那一行,那么IDE就會(huì)打開(kāi)該文件,定位到該行,很容易看 出是哪出現(xiàn)了內(nèi)存泄露。二。檢測(cè)純C+的程序內(nèi)存泄露我試了下用 VisualStudio 建立的 Win32 Console Application和 Win32 Project 項(xiàng)目,結(jié)果 都不能檢測(cè)出內(nèi)存泄露。下面一步一步來(lái)把程序的內(nèi)存泄露檢測(cè)的機(jī)制建立起來(lái)。首先,我們需要知道C運(yùn)行庫(kù)的Debug版本提供了許多檢測(cè)功能,使得我們更容易的 Debug程序。在MSDN中有專門(mén)的章節(jié)講這個(gè),叫做Debug Routines,建議大家先看看里面 的內(nèi)容吧。我們會(huì)用到里面很重要的幾個(gè)函數(shù)。其中最重要的是_Cr
4、tDumpMemoryLeaks;自己看 MSDN里的幫助吧。使用這個(gè)函數(shù),需要包含頭文件crtdbg.h.該函數(shù)只在 Debug 版本才有用,當(dāng)在調(diào)試器下運(yùn)行程序時(shí), _CrtDumpMemoryLeaks 將 在“Output(輸出)”窗口中顯示內(nèi)存泄漏信息。寫(xiě)段代碼試驗(yàn)一下吧,如下:檢測(cè)內(nèi)存泄露版本一:#include “stdafx.h”#includeint _tmain(int argc, _TCHAR* argv)int* p = new int;_CrtDumpMemoryLeaks;return 0;運(yùn)行后,在Output(輸出)窗口,顯示了如下的信息:Detected me
5、mory leaks!Dumping objects -112 normal block at 0 x003AA770, 4 bytes long.Data: 00 00 00 00Object dump complete. 但是這個(gè)只是告訴我們程序有內(nèi)存泄露,到底在哪泄露了一眼看不出來(lái)啊。 看我們的檢測(cè)內(nèi)存泄露版本二:#include “stdafx.h ”#ifdef _DEBUG#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, _FILE_, _LINE_) #else#define DEBUG_CLIENTBLOCK#endif#define
6、_CRTDBG_MAP_ALLOC#include#ifdef _DEBUG#define new DEBUG_CLIENTBLOCK#endifint _tmain(int argc, _TCHAR* argv)int* p = new int;_CrtDumpMemoryLeaks;return 0;該程序定義了幾個(gè)宏,通過(guò)宏將 Debug 版本下的 new 給替換了,新的 new 記錄下了調(diào) 用 new 時(shí)的文件名和代碼行。運(yùn)行后,可以看到如下的結(jié)果:Detected memory leaks!Dumping objects -d:codeconsoletestconsoletest.c
7、pp(21) : 112 client block at 0 x003A38B0, subtype 0, 4 bytes long.Data: 00 00 00 00Object dump complete.呵呵,已經(jīng)和 MFC 程序的效果一樣了,但是等一等。看下如下的代碼吧:int _tmain(int argc, _TCHAR* argv)int* p = new int;_CrtDumpMemoryLeaks;delete p;return 0;運(yùn)行后可以發(fā)現(xiàn)我們刪除了指針,但是它仍然報(bào)內(nèi)存泄露。所以可以想象,每調(diào)用一次 new,程序內(nèi)部都會(huì)將該調(diào)用記錄下來(lái),類(lèi)似于有個(gè)數(shù)組記錄,假如de
8、lete 了,那么就將其從 數(shù)組中刪除,而CrtDumpMemoryLeaks就是把這個(gè)數(shù)組當(dāng)前的狀態(tài)打印出來(lái)。所以除了在必要的時(shí)候Dump出內(nèi)存信息外,最重要的就是在程序退出的時(shí)候需要掉用 次_ CrtDumpMemoryLeaks;假如程序有不止一個(gè)出口,那么我們就需要在多個(gè)地方都調(diào)用該函數(shù)。更進(jìn)一步,假如程序在類(lèi)的析構(gòu)函數(shù)里刪除指針,怎么辦?例如:#include “stdafx.h ”#ifdef _DEBUG#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, _FILE_, _LINE_)#else#define DEBUG_CLIENTBLO
9、CK#endif#define _CRTDBG_MAP_ALLOC#include#ifdef _DEBUG#define new DEBUG_CLIENTBLOCK#endifclass Testpublic:Test _p = new int; Test delete _p; int* _p;int _tmain(int argc, _TCHAR* argv)int* p = new int;delete p;Test t;_CrtDumpMemoryLeaks;return 0;可以看到析構(gòu)函數(shù)在程序退出的時(shí)候才調(diào)用,明明沒(méi)有內(nèi)存泄露,但是這樣的寫(xiě)法還是 報(bào)了。如何改進(jìn)呢,看檢測(cè)內(nèi)存泄露
10、版本三:#include “stdafx.h ”#ifdef _DEBUG#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, _FILE_, _LINE_)#else#define DEBUG_CLIENTBLOCK#endif#define _CRTDBG_MAP_ALLOC#include#ifdef _DEBUG#define new DEBUG_CLIENTBLOCK#endifclass Testpublic:Test _p = new int; Test delete _p; int* _p;int _tmain(int argc, _TCH
11、AR* argv)_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );int* p = new int;delete p;Test t;return 0;_CrtSetDbgFlag(CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); 該語(yǔ)句 在 程 序 退 出 時(shí) 自 動(dòng) 調(diào) 用 _CrtDumpMemoryLeaks. 必 須 同 時(shí) 設(shè) 置 _CRTDBG_ALLOC_MEM_DF 和 _CRTDBG_LEAK_CHECK_DF.這樣,該版本已經(jīng)達(dá)到了 MFC 樣的效果了
12、,但是我覺(jué)得光這樣還不夠,因?yàn)槲覀冎皇窃?Output 窗口中輸出信息,對(duì)開(kāi)發(fā)人員的提醒還不明顯,經(jīng)常會(huì)被遺漏,而且很多人就 算發(fā)現(xiàn)了內(nèi)存泄露,但是不好修復(fù),不會(huì)嚴(yán)重影響到程序外在表現(xiàn),都不會(huì)修復(fù)。怎么樣能 讓開(kāi)發(fā)人員主動(dòng)的修復(fù)內(nèi)存泄露的問(wèn)題呢?記得曾經(jīng)和人配合寫(xiě)程序,我的函數(shù)參數(shù)有要 求,不能為空,但是別人老是傳空值,沒(méi)辦法了,只好在函數(shù)開(kāi)始驗(yàn)證函數(shù)參數(shù),給他 assert 住,這樣程序運(yùn)行時(shí)老是不停的彈出assert,調(diào)試程序那個(gè)煩壓,最后其他程序員煩了,就把 這個(gè)問(wèn)題給改好了,輸入?yún)?shù)就正確了。所以我覺(jué)得咱要讓程序員主動(dòng)去做一件事,首先要 讓他覺(jué)得做這個(gè)事是能減輕自己負(fù)擔(dān),讓自己工作輕松
13、的。呵呵,那咱們也這樣,當(dāng)程序退 出時(shí),檢測(cè)到內(nèi)存泄露就讓程序提示出來(lái)。看檢測(cè)內(nèi)存泄露版本四:#include “stdafx.h ”#include#ifdef _DEBUG#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, _FILE_, _LINE_)#else#define DEBUG_CLIENTBLOCK#endif#define _CRTDBG_MAP_ALLOC#include#ifdef _DEBUG#define new DEBUG_CLIENTBLOCK#endifvoid Exitint i = _CrtDumpMemoryLea
14、ks;assert( i = 0);int _tmain(int argc, _TCHAR* argv)atexit(Exit);int* p = new int;return 0;該版本會(huì)在程序退出時(shí)檢查內(nèi)存泄露,假如存在就會(huì)彈出提示對(duì)話框。atexit(Exit);設(shè)置了在程序退出時(shí)執(zhí)行Exit函數(shù)。Exit函數(shù)中,假如存在內(nèi)存泄露, _CrtDumpMemoryLeaks 會(huì)返回非 0 值,就會(huì)被 assert 住了。到這個(gè)版本已經(jīng)達(dá)到可以使用的程度了。但是我們還可以做些改進(jìn),因?yàn)檎嬉獪?zhǔn)確的檢 測(cè)到代碼中所有的內(nèi)存泄露,需要把代碼中的#define拷貝到所有使用new的文件中。 不可能每個(gè)文件都拷貝這么多代碼,所以我們可以將他提取出來(lái),放在一個(gè)文件中,比如我 是放在 KDetectMemoryLeak.h 中,該文件內(nèi)容如下:#pragma once#ifdef _DEBUG#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, _FILE_, _LINE_)#el
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024華電江西發(fā)電有限公司所屬企業(yè)面向系統(tǒng)內(nèi)外公開(kāi)招聘4人筆試參考題庫(kù)附帶答案詳解
- 2024中煤(深圳)研究院有限責(zé)任公司面向中國(guó)中煤內(nèi)部及社會(huì)公開(kāi)招聘19人筆試參考題庫(kù)附帶答案詳解
- 2024中國(guó)鐵建昆侖投資集團(tuán)有限公司經(jīng)營(yíng)機(jī)構(gòu)有關(guān)崗位招聘26人筆試參考題庫(kù)附帶答案詳解
- 綠色思維的家居設(shè)計(jì)
- 學(xué)校管理經(jīng)驗(yàn)交流校長(zhǎng)匯報(bào)發(fā)言:解鎖學(xué)校高效管理的“實(shí)”踐密碼
- 2024北京海淀區(qū)四年級(jí)(下)期末數(shù)學(xué)試題及答案
- 2025窗戶防盜護(hù)欄安裝合同范本
- 大學(xué)生電子商務(wù)“創(chuàng)新 創(chuàng)意 創(chuàng)業(yè)”挑戰(zhàn)賽山西賽區(qū)執(zhí)行方案
- 1個(gè)人形象設(shè)計(jì)公司商業(yè)計(jì)劃書(shū)
- 手足口病診斷及治療
- 《幼兒教育政策與法規(guī)》課件-單元4 幼兒園的保育和教育
- 2024年私募基金爭(zhēng)議解決研究報(bào)告之一:私募基金管理人謹(jǐn)慎勤勉義務(wù)之邊界探析-國(guó)楓研究院
- 環(huán)衛(wèi)設(shè)施設(shè)備更新實(shí)施方案
- 廣東省高州市2023-2024學(xué)年高一下學(xué)期期中考試數(shù)學(xué)
- 2024年高等教育文學(xué)類(lèi)自考-06050人際關(guān)系心理學(xué)考試近5年真題附答案
- 福建省公路水運(yùn)工程試驗(yàn)檢測(cè)費(fèi)用參考指標(biāo)
- 地震監(jiān)測(cè)設(shè)備質(zhì)量檢測(cè)手冊(cè)
- 110kV平西變電站工程施工組織設(shè)計(jì)
- 09幾何大題綜合-【黃金沖刺】考前10天中考數(shù)學(xué)極限滿分沖刺(浙江專用)原卷版+解析
- 信創(chuàng)虛擬化及云平臺(tái)解決方案
- ICD-10疾病編碼完整版
評(píng)論
0/150
提交評(píng)論