国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
VC內(nèi)存泄露檢測(cè) - VC常見錯(cuò)誤與技巧
VC內(nèi)存泄露檢測(cè)
介紹:
動(dòng)態(tài)分配、回收內(nèi)存是c/c++編程語(yǔ)言一個(gè)最強(qiáng)的特點(diǎn),但是中國(guó)哲學(xué)家孫(sun tzu,我不知道是誰(shuí)?那位知道?) 指出,最強(qiáng)的同時(shí)也是最弱的。這句話對(duì)c/c++應(yīng)用來(lái)說(shuō)非常正確,在內(nèi)存處理出錯(cuò)的地方通常就是bugs產(chǎn)生的地方。一個(gè)最敏感和難檢測(cè)的bug就是內(nèi)存泄漏-沒有把前邊分配的內(nèi)存成功釋放,一個(gè)小的內(nèi)存泄漏可能不需要太注意,但是程序泄漏大塊內(nèi)存,或者漸增式的泄漏內(nèi)存可能引起的現(xiàn)象是:先是性能低下,再就是引起復(fù)雜的內(nèi)存耗盡錯(cuò)誤。最壞的是,一個(gè)內(nèi)存泄漏程序可能用完了如此多的內(nèi)存以至于引起其他的程序出錯(cuò),留給用戶的是不能知道錯(cuò)誤到底來(lái)自哪里。另外,一個(gè)看上去無(wú)害的內(nèi)存泄漏可能是另一個(gè)問(wèn)題的先兆。幸運(yùn)的是vc++debuger和crt庫(kù)提供了一組有效的檢測(cè)和定位內(nèi)存泄漏的工具。本文描述如何使用這些工具有效和系統(tǒng)的排除內(nèi)存泄漏。
啟動(dòng)內(nèi)存泄漏檢測(cè):
主要的檢測(cè)工具是debuger和crt堆除錯(cuò)函數(shù)。要使除錯(cuò)函數(shù)生效,必須要在你的程序中包含以下幾個(gè)語(yǔ)句:
#define _crtdbg_map_alloc
#include "stdlib.h"
#include "crtdbg.h"
并且這些#include 語(yǔ)句必須按上邊給出的順序使用。如果你改變了順序,可能導(dǎo)致使用的函數(shù)工作不正常。包含crtdbg.h的作用是用malloc和free函數(shù)的debug版本(_malloc_dbg 和 _free_dbg)來(lái)替換他們,他們能跟蹤內(nèi)存分配和回收。這個(gè)替換僅僅是在debug狀態(tài)下生效,relese版本中還是使用普通的malloc和free函數(shù)。
上面的#define語(yǔ)句使用crt堆函數(shù)相應(yīng)的debug版本來(lái)替換正常的堆函數(shù)。這個(gè)語(yǔ)句不是必需的,但是沒有他,你可能會(huì)失去一些有用的內(nèi)存泄漏信息。
你一旦在你的程序中增加了以上的語(yǔ)句,你可以通過(guò)在程序中增加_crtdumpmemoryleaks();函數(shù)來(lái)輸出內(nèi)存泄漏信息。
//呵呵感謝網(wǎng)友提出問(wèn)題,由于是轉(zhuǎn)的貼,未經(jīng)作者同意不便修改,所以有異議的地方我會(huì)注明的_crtdumpmemoryleaks(); 大小寫有問(wèn)題 都要改成如下_CrtDumpMemoryLeaks();  --by帥得不敢出門
當(dāng)你在debuger下運(yùn)行你的程序時(shí),_crtdumpmemoryleaks 顯示內(nèi)存泄漏信息在output窗口的debug標(biāo)簽項(xiàng)里。內(nèi)存泄漏信息舉例如下:
detected memory leaks!
dumping objects ->
c:\program files\visual studio\myprojects\leaktest\leaktest.cpp(20) : {18}
normal block at 0x00780e80, 64 bytes long.
data: < > cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd
object dump complete.
如果你沒有使用 #define _crtdbg_map_alloc語(yǔ)句的話,輸出信息將如下:
detected memory leaks!
dumping objects ->
{18} normal block at 0x00780e80, 64 bytes long.
data: < > cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd
object dump complete.
像你所看到的,當(dāng)_crtdbg_map_alloc 被定義后_crtdumpmemoryleaks給了你很多有用的信息。在沒有定義_crtdbg_map_alloc 的情況下,顯示信息包含:
1.內(nèi)存分配的編號(hào)(大括弧中的數(shù)字);
2.內(nèi)存快的類型(普通型、客戶端型、crt型);
3.16進(jìn)制表示的內(nèi)存位置;
4.內(nèi)存快的大??;
5.前16bytes的內(nèi)容。
如果定義了_crtdbg_map_alloc ,輸出信息還包含當(dāng)前泄漏內(nèi)存是在那個(gè)文件中被分配的定位信息。文件名后圓括弧中的數(shù)字是行數(shù)。如果你雙擊這行信息,
c:\program files\visual studio\myprojects\leaktest\leaktest.cpp(20) : {18}
normal block at 0x00780e80, 64 bytes long.
光標(biāo)就會(huì)跳轉(zhuǎn)到原文件中分配這個(gè)內(nèi)存的行前。選擇output中的題是行,按f4能達(dá)到同樣的效果。
// 我在VC6.0測(cè)試下#define _crtdbg_map_alloc這個(gè)大小寫也有問(wèn)題應(yīng)該為
#define _CRTDBG_MAP_ALLOC 而且定義這個(gè)時(shí)無(wú)法定位到你寫的有內(nèi)存泄漏的代碼處 我測(cè)試的new[]而不delete[]會(huì)定位到CRTDBG.H 中的inline void* __cdecl operator new(unsigned int s)
{ return ::operator new(s, _NORMAL_BLOCK, __FILE__, __LINE__); }
--by帥得不敢出門
使用using _crtsetdbgflag:
如果你的程序的退出點(diǎn)只有一個(gè)的話,調(diào)用_crtdumpmemoryleaks將是非常容易。但是,如果你的程序有多個(gè)退出點(diǎn)話會(huì)是什么樣一個(gè)情況?如果不想在每個(gè)退出點(diǎn)都調(diào)用_crtdumpmemoryleaks,你可以在程序的開始包含以下調(diào)用:
_crtsetdbgflag( _crtdbg_alloc_mem_df | _crtdbg_leak_check_df);
這個(gè)語(yǔ)句會(huì)在你的程序結(jié)束時(shí)自動(dòng)調(diào)用_crtdumpmemoryleaks,但是你必須象前邊提到的那樣設(shè)置_crtdbg_alloc_mem_df 和 _crtdbg_leak_check_df這兩個(gè)標(biāo)志位。
上面這句大小寫有問(wèn)題的 改成_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); 而且包含了CRTDBG.H 頭文件,而這個(gè)頭文件中已有
#define _CRTDBG_ALLOC_MEM_DF        0x01  /* Turn on debug allocation */
#define _CRTDBG_DELAY_FREE_MEM_DF   0x02  /* Don't actually free memory */就無(wú)需再自己設(shè)置上面說(shuō)的那兩個(gè)標(biāo)志位了
--by帥得不敢出門
介紹一下內(nèi)存塊的類型:
就象前面指出的,一個(gè)內(nèi)存泄漏信息指出每個(gè)內(nèi)存泄漏塊的類型為普通、客戶端或者crt型。在實(shí)際程序中,普通型和客戶端型式最常見的類型。
普通型內(nèi)存塊是你的程序平常分配的內(nèi)存類型。
客戶端型內(nèi)存塊是mfc程序給需要析構(gòu)的對(duì)
象分配的內(nèi)存塊。mfc的new操作可以選擇普通型或客戶端型中合適的一種作為將要被創(chuàng)建的對(duì)象的內(nèi)存塊類型。
crt內(nèi)存塊是crt庫(kù)為自己使用而分配的內(nèi)存塊。crt在處理自己的釋放內(nèi)存操作時(shí)使用這些塊,所以在內(nèi)存泄漏報(bào)告中這種類型并不常見,除非發(fā)生嚴(yán)重異常(例如:crt庫(kù)出錯(cuò))。
還有兩種類型你在內(nèi)存泄漏信息中看不到:
自由塊,它是已經(jīng)被釋放的內(nèi)存塊;
忽略塊,它是已經(jīng)被特殊標(biāo)示的內(nèi)存塊。
設(shè)置crt報(bào)告的格式:
在默認(rèn)情況下,_crtdumpmemoryleaks輸出的內(nèi)存泄漏信息就象前邊描述的那樣。你可以使用_crtsetreportmode
//其實(shí)是_CrtSetReportMode() 可見大小寫都沒對(duì)上 ,后面也是  我就不一一解釋了
讓這些輸出信息輸出到其他地方。如果你使用一個(gè)庫(kù),它可能要使輸出信息到其他的地方,在這種情況下,你可以使用_crtsetreportmode( _crt_error, _crtdbg_mode_debug );語(yǔ)句使輸出信息重新定位到output窗口。
根據(jù)內(nèi)存分配編號(hào)設(shè)置斷點(diǎn):
內(nèi)存泄漏報(bào)告中的文件名和行數(shù)告訴你內(nèi)存泄漏的位置,但是知道內(nèi)存泄漏位置不是總是能找到問(wèn)題所在。在一個(gè)運(yùn)行的程序中一個(gè)內(nèi)存分配操作可能被調(diào)用多次,但是內(nèi)存泄漏可能只發(fā)生在其中的某次操作中。為了確認(rèn)問(wèn)題所在,你除了知道泄漏的位置之外,你還必須要知道發(fā)生泄漏的條件。內(nèi)存分配編號(hào)使得解決這個(gè)問(wèn)題成為可能。這個(gè)數(shù)字就在文件名、行數(shù)之后的大括弧內(nèi)。例如,在上面的輸出中“18”就是內(nèi)存分配編號(hào),它的意思是你程序中的內(nèi)存泄漏發(fā)生在第18次分配操作中。
crt庫(kù)對(duì)正在運(yùn)行程序中所有的內(nèi)存塊分配進(jìn)行計(jì)數(shù),包括自身的內(nèi)存分配,或者其他庫(kù)(象mfc)。一個(gè)對(duì)象的分配編號(hào)是n表示第n個(gè)對(duì)象被分配,但是它可能并不表示第n個(gè)對(duì)象通過(guò)代碼被分配(在大多數(shù)情況下它們并不相同)。
你可以根據(jù)內(nèi)存分配編號(hào)在內(nèi)存被分配的位置設(shè)置斷點(diǎn)。先在程序開始部分附近設(shè)置一個(gè)斷點(diǎn),當(dāng)你的程序在斷點(diǎn)處停止后,你可以通過(guò)quickwatch對(duì)話框或者watch窗口來(lái)設(shè)置內(nèi)存分配斷點(diǎn)。在watch窗口中的name列中輸入_crtbreakalloc,如果你使用的是多線程dll版本的crt庫(kù)的話你必須包含上下文轉(zhuǎn)換 {,,msvcrtd.dll}_crtbreakalloc。完成后按回車,debugger處理這次調(diào)用,并且把返回值顯示在value列中。如果你沒有設(shè)置內(nèi)存分配斷點(diǎn)的話返回值是-1。在value列中輸入你想設(shè)置的分配數(shù),例如18。
你在自己感興趣的內(nèi)存分配位置設(shè)置斷點(diǎn)后,你可以繼續(xù)debugging。細(xì)心的運(yùn)行你的程序在相同的條件下,這樣才能保證內(nèi)存分配的順序不致發(fā)生變化。當(dāng)程序在特定的內(nèi)存分配處停下來(lái)后, 你可以查看call 窗口和其他的debugger信息來(lái)分析此次內(nèi)存分配的條件。如果有必要你可以繼續(xù)運(yùn)行程序,看一看這個(gè)對(duì)象有什么變化,或許可以得知為什么內(nèi)存沒有被正確的釋放。
盡管這個(gè)操作非常容易,但是如果你高興的話也可以在代碼中設(shè)置斷點(diǎn)。在代碼中增加一行代碼_crtbreakalloc = 18;另外也可以通過(guò)_crtsetbreakalloc(18)來(lái)完成設(shè)置。
比較內(nèi)存狀態(tài)
另一個(gè)定位內(nèi)存泄漏的方法是在重要位置捕捉應(yīng)用程序的“內(nèi)存快照”。crt庫(kù)提供了一個(gè)結(jié)構(gòu)體類型 _crtmemstate,使用它你可以保存內(nèi)存狀態(tài)的快照(當(dāng)前狀態(tài))。
_crtmemstate s1, s2, s3;   // _CrtMemState
為了得到一個(gè)快照,可以把一個(gè)_crtmemstate 結(jié)構(gòu)體傳給_crtmemcheckpoint 函數(shù),這個(gè)函數(shù)可以把當(dāng)前的內(nèi)存狀態(tài)填充在結(jié)構(gòu)體中:
_crtmemcheckpoint( &s1 );
你可以通過(guò)把結(jié)構(gòu)體_crtmemstate 傳給_crtmemdumpstatistics函數(shù)來(lái)輸出結(jié)構(gòu)體中的內(nèi)容。
_crtmemdumpstatistics( &s3 );( &s1 );
它輸出的信息如下:
0 bytes in 0 free blocks.
0 bytes in 0 normal blocks.
3071 bytes in 16 crt blocks.
0 bytes in 0 ignore blocks.
0 bytes in 0 client blocks.
largest number used: 3071 bytes.
total allocations: 3764 bytes.
為了得知一段代碼中是否有內(nèi)存泄漏,你可以在這段代碼的開始和完成處分別拍一個(gè)快照,然后調(diào)用_crtmemdifference函數(shù)來(lái)比較兩個(gè)狀態(tài):
_crtmemcheckpoint( &s1 );
// memory allocations take place here
_crtmemcheckpoint( &s2 );
if ( _crtmemdifference( &s3, &s1, &s2) )
_crtmemdumpstatistics( &s3 );
就像名字中暗示的那樣,_crtmemdifference比較兩個(gè)內(nèi)存狀態(tài),并且產(chǎn)生一個(gè)結(jié)果(第一個(gè)參數(shù))。把 _crtmemcheckpoint 放在程序的開始和結(jié)尾,調(diào)用_crtmemdifference 來(lái)比較結(jié)果,這也是一種檢測(cè)內(nèi)存泄漏的方法。如果發(fā)現(xiàn)內(nèi)存泄漏,你可以使用_crtmemcheckpoint把程序分成兩半分別使用上述方法來(lái)檢測(cè)內(nèi)存泄漏,這樣就是使用二分法來(lái)檢查內(nèi)存泄漏。
原文地址http://www.aaa-nnn.cn/it/p79/J799746.shtml
發(fā)表于: 2008-04-17,修改于: 2008-05-15 20:51 已瀏覽764次,有評(píng)論3條推薦投訴
網(wǎng)友評(píng)論
本站網(wǎng)友 時(shí)間:2008-05-15 15:54:00 IP地址:121.35.51.★
抄別人的東西就算了,你不把里面的錯(cuò)誤改正過(guò)來(lái)那就太沒人性了,抄了也不改進(jìn)一下(里面有些東西沒有描述清楚,會(huì)誤導(dǎo)人的).
以后抄別人的東西機(jī)的改進(jìn)一下,或者自己試成功后再發(fā)表
Blog作者的回復(fù):
此貼我文尾已經(jīng)給出原文鏈接 只是學(xué)習(xí)需要所以轉(zhuǎn)來(lái)隨時(shí)查閱的 有錯(cuò)誤請(qǐng)指出  如果覺得不清楚  可以查看以下這兩個(gè)帖子
檢查C++內(nèi)存泄露的方法http://blog.chinaunix.net/u2/64540/showart_681410.html
淺談C/C++內(nèi)存泄漏及其檢測(cè)工具
http://blog.chinaunix.net/u2/64540/showart_681416.html
帥得不敢出門 時(shí)間:2008-05-15 20:52:27 IP地址:125.77.105.★
感謝指出錯(cuò)誤  已經(jīng)加了修正  有問(wèn)題請(qǐng)大家指出  都是大小寫的問(wèn)題  后面有幾個(gè)我就不改了
帥得不敢出門 時(shí)間:2008-05-15 21:01:37 IP地址:125.77.105.★
//后面的也補(bǔ)上吧  并加了自己的代碼
_CrtMemState s1,s2,s3;
_CrtMemCheckpoint(&s1);
int *p = new int[2];
_CrtMemCheckpoint(&s1);
if (_CrtMemDifference(&s3, &s1, &s2))
{
_CrtMemDumpStatistics(&s3);
}
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
在VisualC++中檢測(cè)和隔離內(nèi)存泄漏
VC使用CRT調(diào)試功能來(lái)檢測(cè)內(nèi)存泄漏
關(guān)于MFC下檢查和消除內(nèi)存泄露的技巧- 教程中心- 中科軟件園
VC++ 6.0 中如何使用 CRT 調(diào)試功能來(lái)檢測(cè)內(nèi)存泄漏(轉(zhuǎn)) - bairny的專欄...
VC++ 6.0 中如何使用 CRT 調(diào)試功能來(lái)檢測(cè)內(nèi)存泄漏
Finding Memory Leaks Using the CRT Library
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服