亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

檢查MFC程序的內存泄露

2019-11-06 05:26:56
字體:
來源:轉載
供稿:網友

1、在stdafx.h頭文件中添加兩行代碼//內存泄露檢測

#define _CRTDBG_MAP_ALLOC#include <stdlib.h>#include <crtdbg.h>

// 一般在入口函數一開始添加以下代碼   _CrtDumpMemoryLeaks();   _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );   

該語句在程序退出時自動調用 _CrtDumpMemoryLeaks。必須同時設置 _CRTDBG_ALLOC_MEM_DF 和 _CRTDBG_LEAK_CHECK_DF 兩個位域,如上所示

 介紹:  動態分配、回收內存是C/C++編程語言一個最強的特點,但是中國哲學家孫(Sun Tzu,我不知道是誰?那位知道?) 指出,最強的同時也是最弱的。這句話對C/C++應用來說非常正確,在內存處理出錯的地方通常就是BUGS產生的地方。一個最敏感和難檢測的BUG就是內存泄漏-沒有把前邊分配的內存成功釋放,一個小的內存泄漏可能不需要太注意,但是程序泄漏大塊內存,或者漸增式的泄漏內存可能引起的現象是:先是性能低下,再就是引起復雜的內存耗盡錯誤。最壞的是,一個內存泄漏程序可能用完了如此多的內存以至于引起其他的程序出錯,留給用戶的是不能知道錯誤到底來自哪里。另外,一個看上去無害的內存泄漏可能是另一個問題的先兆。幸運的是VC++DEBUGER和CRT庫提供了一組有效的檢測和定位內存泄漏的工具。本文描述如何使用這些工具有效和系統的排除內存泄漏。     啟動內存泄漏檢測:  主要的檢測工具是DEBUGER和CRT堆除錯函數。要使除錯函數生效,必須要在你的程序中包含以下幾個語句:    #define _CRTDBG_MAP_ALLOC  #include "stdlib.h"  #include "crtdbg.h"    并且這些#include 語句必須按上邊給出的順序使用。如果你改變了順序,可能導致使用的函數工作不正常。包含crtdbg.h的作用是用malloc和free函數的debug版本(_malloc_dbg 和 _free_dbg)來替換他們,他們能跟蹤內存分配和回收。這個替換僅僅是在debug狀態下生效,Relese版本中還是使用普通的malloc和free函數?! ∩厦娴?define語句使用crt堆函數相應的debug版本來替換正常的堆函數。這個語句不是必需的,但是沒有他,你可能會失去一些有用的內存泄漏信息?! ∧阋坏┰谀愕某绦蛑性黾恿艘陨系恼Z句,你可以通過在程序中增加_CrtDumpMemoryLeaks();函數來輸出內存泄漏信息?! ‘斈阍赿ebuger下運行你的程序時,_CrtDumpMemoryLeaks 顯示內存泄漏信息在OutPut窗口的Debug標簽項里。內存泄漏信息舉例如下:    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語句的話,輸出信息將如下:    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.    像你所看到的,當_CRTDBG_MAP_ALLOC 被定義后_CrtDumpMemoryLeaks給了你很多有用的信息。在沒有定義_CRTDBG_MAP_ALLOC 的情況下,顯示信息包含:  1.內存分配的編號(大括弧中的數字);  2.內存快的類型(普通型、客戶端型、CRT型);  3.16進制表示的內存位置;  4.內存快的大小;  5.前16bytes的內容?!   ∪绻x了_CRTDBG_MAP_ALLOC ,輸出信息還包含當前泄漏內存是在那個文件中被分配的定位信息。文件名后圓括弧中的數字是行數。如果你雙擊這行信息,    C:/PROGRAM FILES/VISUAL STUDIO/MyProjects/leaktest/leaktest.cpp(20) : {18}   normal block at 0x00780E80, 64 bytes long.    光標就會跳轉到原文件中分配這個內存的行前。選擇Output中的題是行,按F4能達到同樣的效果?! ∈褂肬sing _CrtSetDbgFlag:  如果你的程序的退出點只有一個的話,調用_CrtDumpMemoryLeaks將是非常容易。但是,如果你的程序有多個退出點話會是什么樣一個情況?如果不想在每個退出點都調用_CrtDumpMemoryLeaks,你可以在程序的開始包含以下調用:    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

這個語句會在你的程序結束時自動調用_CrtDumpMemoryLeaks,但是你必須象前邊提到的那樣設置_CRTDBG_ALLOC_MEM_DF 和 _CRTDBG_LEAK_CHECK_DF這兩個標志位?!  〗榻B一下內存塊的類型:  就象前面指出的,一個內存泄漏信息指出每個內存泄漏塊的類型為普通、客戶端或者CRT型。在實際程序中,普通型和客戶端型式最常見的類型。  普通型內存塊是你的程序平常分配的內存類型?! 】蛻舳诵蛢却鎵K是MFC程序給需要析構的對象分配的內存塊。MFC的new操作可以選擇普通型或客戶端型中合適的一種作為將要被創建的對象的內存塊類型?! RT內存塊是CRT庫為自己使用而分配的內存塊。CRT在處理自己的釋放內存操作時使用這些塊,所以在內存泄漏報告中這種類型并不常見,除非發生嚴重異常(例如:CRT庫出錯)?!   ∵€有兩種類型你在內存泄漏信息中看不到:  自由塊,它是已經被釋放的內存塊;  忽略塊,它是已經被特殊標示的內存塊?! ≡O置CRT報告的格式:  在默認情況下,_CrtDumpMemoryLeaks輸出的內存泄漏信息就象前邊描述的那樣。你可以使用_CrtSetReportMode讓這些輸出信息輸出到其他地方。如果你使用一個庫,它可能要使輸出信息到其他的地方,在這種情況下,你可以使用_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );語句使輸出信息重新定位到Output窗口。    根據內存分配編號設置斷點:  內存泄漏報告中的文件名和行數告訴你內存泄漏的位置,但是知道內存泄漏位置不是總是能找到問題所在。在一個運行的程序中一個內存分配操作可能被調用多次,但是內存泄漏可能只發生在其中的某次操作中。為了確認問題所在,你除了知道泄漏的位置之外,你還必須要知道發生泄漏的條件。內存分配編號使得解決這個問題成為可能。這個數字就在文件名、行數之后的大括弧內。例如,在上面的輸出中“18”就是內存分配編號,它的意思是你程序中的內存泄漏發生在第18次分配操作中?! RT庫對正在運行程序中所有的內存塊分配進行計數,包括自身的內存分配,或者其他庫(象MFC)。一個對象的分配編號是n表示第n個對象被分配,但是它可能并不表示第N個對象通過代碼被分配(在大多數情況下它們并不相同)。  你可以根據內存分配編號在內存被分配的位置設置斷點。先在程序開始部分附近設置一個斷點,當你的程序在斷點處停止后,你可以通過QuickWatch對話框或者Watch窗口來設置內存分配斷點。在Watch窗口中的Name列中輸入_crtBreakAlloc,如果你使用的是多線程DLL版本的CRT庫的話你必須包含上下文轉換 {,,msvcrtd.dll}_crtBreakAlloc。完成后按回車,debugger處理這次調用,并且把返回值顯示在value列中。如果你沒有設置內存分配斷點的話返回值是-1。在value列中輸入你想設置的分配數,例如18?! ∧阍谧约焊信d趣的內存分配位置設置斷點后,你可以繼續debugging。細心的運行你的程序在相同的條件下,這樣才能保證內存分配的順序不致發生變化。當程序在特定的內存分配處停下來后, 你可以查看Call 窗口和其他的debugger信息來分析此次內存分配的條件。如果有必要你可以繼續運行程序,看一看這個對象有什么變化,或許可以得知為什么內存沒有被正確的釋放?!   ”M管這個操作非常容易,但是如果你高興的話也可以在代碼中設置斷點。在代碼中增加一行代碼_crtBreakAlloc = 18;另外也可以通過_CrtSetBreakAlloc(18)來完成設置?! ”容^內存狀態  另一個定位內存泄漏的方法是在重要位置捕捉應用程序的“內存快照”。CRT庫提供了一個結構體類型 _CrtMemState,使用它你可以保存內存狀態的快照(當前狀態)?!   CrtMemState s1, s2, s3;    為了得到一個快照,可以把一個_CrtMemState 結構體傳給_CrtMemCheckpoint 函數,這個函數可以把當前的內存狀態填充在結構體中:    _CrtMemCheckpoint( &s1 );    你可以通過把結構體_CrtMemState 傳給_CrtMemDumpStatistics函數來輸出結構體中的內容。  _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.    為了得知一段代碼中是否有內存泄漏,你可以在這段代碼的開始和完成處分別拍一個快照,然后調用_CrtMemDifference函數來比較兩個狀態:    _CrtMemCheckpoint( &s1 );  // memory allocations take place here  _CrtMemCheckpoint( &s2 );    if ( _CrtMemDifference( &s3, &s1, &s2) )   _CrtMemDumpStatistics( &s3 );    就像名字中暗示的那樣,_CrtMemDifference比較兩個內存狀態,并且產生一個結果(第一個參數)。把 _CrtMemCheckpoint 放在程序的開始和結尾,調用_CrtMemDifference 來比較結果,這也是一種檢測內存泄漏的方法。如果發現內存泄漏,你可以使用_CrtMemCheckpoint把程序分成兩半分別使用上述方法來檢測內存泄漏,這樣就是使用二分法來檢查內存泄漏。

可以封裝在一個類中,程序中直接調用: CDebug::Debug();===========================================================================// Debug.h: interface for the CDebug class.//---------------------------------------------------------------------------------// 內存泄露信息示例 : // {49} normal block at 0x00382F78, 40 bytes long.// Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD //---------------------------------------------------------------------------------// 顯示信息包含://  1.內存分配的編號(大括弧中的數字);//  2.內存快的類型(普通型、客戶端型、CRT型);// <1>普通型內存塊是你的程序平常分配的內存類型。// <2>客戶端型內存塊是MFC程序給需要析構的對象分配的內存塊。// <3>CRT內存塊是CRT庫為自己使用而分配的內存塊。// <4>自由塊,它是已經被釋放的內存塊;// <5>忽略塊,它是已經被特殊標示的內存塊。//  3.16進制表示的內存位置;//  4.內存快的大?。?/  5.前16bytes的內容。//////////////////////////////////////////////////////////////////////#if !defined(AFX_DEBUG_H__6B201A16_E36F_4830_A4F5_BD2207106871__INCLUDED_)#define AFX_DEBUG_H__6B201A16_E36F_4830_A4F5_BD2207106871__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000// 一般在入口函數cpp中添加以下定義和頭文件   CRT庫#define _CRTDBG_MAP_ALLOC   #include <stdlib.h>   #include <crtdbg.h>  // 內存泄露信息中顯示文件名和代碼行號 如果出現重定義可以#ifdef _DEBUG#define new   new(_NORMAL_BLOCK, __FILE__, __LINE__)#endifclass CDebug  {private:CDebug();virtual ~CDebug();public:static void Debug(){ // 一般在入口函數一開始添加以下代碼   _CrtDumpMemoryLeaks();   _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );   };// 根據內存分配編號設置斷點:static void Debug(unsigned int num){//num就是剛剛檢測出來的內存泄露的地方大括號內的數字,跳轉到內存泄露的地方 _CrtSetBreakAlloc(num);   }};#endif // !defined(AFX_DEBUG_H__6B201A16_E36F_4830_A4F5_BD2207106871__INCLUDED_)===========================================================================


上一篇:POJ P3259 Wormholes

下一篇:變量類型

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久久久久香蕉网| 91精品综合久久久久久五月天| 久久精品男人天堂| 国产专区欧美专区| 7777精品久久久久久| 国产精品一区二区久久| 国产女人精品视频| 精品伊人久久97| 欧美在线日韩在线| 亚洲xxxx妇黄裸体| 日韩成人中文字幕| 日韩高清免费在线| 欧美午夜www高清视频| 亚洲天堂男人天堂女人天堂| 久久精品电影一区二区| 欧美一区二区.| 欧美成在线观看| 亚洲福利视频久久| 日韩精品丝袜在线| 色妞一区二区三区| 国产精品久久久亚洲| 97精品久久久中文字幕免费| 久久久久在线观看| 日韩三级影视基地| 国产欧美精品xxxx另类| 国产精品美女主播在线观看纯欲| 国色天香2019中文字幕在线观看| 九九九久久久久久| 懂色av影视一区二区三区| 91丨九色丨国产在线| 国产精品91在线| 国产69精品久久久久久| 激情成人中文字幕| 欧美成人免费va影院高清| 日韩精品在线观看一区| 日韩欧美在线国产| 日本高清视频一区| 亚洲一区二区三区xxx视频| 日韩av中文在线| 91中文精品字幕在线视频| 中文国产成人精品| 97在线观看视频国产| 国产精品久久色| 97不卡在线视频| 亚洲男人天天操| 久久频这里精品99香蕉| 国产久一一精品| 亚洲午夜激情免费视频| 亚洲激情 国产| 国产小视频91| 亚洲国产精品热久久| 亚洲精品一区二区三区婷婷月| 久久99久国产精品黄毛片入口| 奇米4444一区二区三区| 日韩精品免费电影| 一区二区三区视频免费在线观看| 亚洲热线99精品视频| 欧美一区二粉嫩精品国产一线天| 成人性生交大片免费观看嘿嘿视频| 丝袜情趣国产精品| 狠狠躁夜夜躁久久躁别揉| 深夜福利亚洲导航| 亚洲欧洲一区二区三区久久| 亚洲www在线| 一区二区三区回区在观看免费视频| 日韩中文综合网| 国产精品国模在线| 久久精品久久久久| 欧美一区二区三区免费视| 国产精品综合网站| 亚洲欧美激情另类校园| 欧美在线一级va免费观看| 国产精品视频网址| 欧美性猛交xxxx免费看漫画| 成人在线视频网| 亚洲精品成人久久久| 久久国产精品偷| 这里只有精品视频| 久久久久亚洲精品国产| 久久黄色av网站| 91po在线观看91精品国产性色| 精品国产电影一区| 在线日韩精品视频| 91免费看国产| 国产91在线播放精品91| 在线看福利67194| 色阁综合伊人av| 久久久久久久久久久免费精品| 成人黄色大片在线免费观看| 久久亚洲电影天堂| 俺去亚洲欧洲欧美日韩| 久久在线观看视频| 欧美高清第一页| www.欧美三级电影.com| 亚洲成人黄色网址| 欧美精品videossex性护士| 亚洲a区在线视频| 亚洲少妇激情视频| 久热精品视频在线免费观看| 成人性生交大片免费观看嘿嘿视频| 国内精品久久久久久影视8| 青草青草久热精品视频在线观看| 亚洲最大激情中文字幕| 久久成人综合视频| 欧美日产国产成人免费图片| 久久av红桃一区二区小说| 国内精品久久久久影院 日本资源| 国产亚洲在线播放| 九九精品在线视频| 欧美日韩在线视频一区| 日韩一区视频在线| 91麻豆国产语对白在线观看| 热久久99这里有精品| 成人午夜高潮视频| 亚洲free嫩bbb| 亚洲一区亚洲二区亚洲三区| 在线激情影院一区| 97人人做人人爱| 成人黄色免费看| 久久久久久噜噜噜久久久精品| 国产中文字幕亚洲| 国产精品香蕉av| 午夜精品三级视频福利| 精品国产91久久久| 国产91精品久久久久| 国产精品一区二区三| 国内精品美女av在线播放| 日韩欧美在线免费观看| 深夜精品寂寞黄网站在线观看| 亚洲人成网站在线播| 91免费人成网站在线观看18| 日韩精品中文字幕在线观看| 高清欧美性猛交| 在线不卡国产精品| 国产一区二区三区高清在线观看| 国产一区二区三区免费视频| 66m—66摸成人免费视频| 国产在线视频一区| 亚洲乱码av中文一区二区| 国产精品久久久久久久av大片| 欧美午夜宅男影院在线观看| 国产性色av一区二区| 国产午夜精品视频| 亚洲自拍偷拍第一页| 久久久久久有精品国产| 国产精品视频白浆免费视频| 久久久女女女女999久久| 亚洲国产私拍精品国模在线观看| 欧美孕妇性xx| 国产成人97精品免费看片| 中文字幕精品一区久久久久| 日韩精品999| 欧美激情区在线播放| 成人午夜两性视频| 91免费精品国偷自产在线| 欧美精品福利视频| 欧洲日韩成人av| 亚洲电影免费观看高清完整版在线观看| 精品无码久久久久久国产| xxx欧美精品| 欧美在线一级va免费观看| 日本成人激情视频| 日韩va亚洲va欧洲va国产| 在线观看国产精品淫|