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

Thronds

一問你會什么 二問你做出過什么 三問你為了什么

  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
  36 隨筆 :: 0 文章 :: 56 評論 :: 0 Trackbacks

前序:此篇文章為轉載,出處不詳,網上對這篇文章的轉載鋪天蓋地,不過這個只是在VC下面的檢測方法,那么在其他操作系統和編譯平臺下面,又當如何檢測和排除內存泄漏呢?文章繼續補充中..

摘要:

本文描述了如何使用VC++CRT庫提供的工具定位和排除內存泄漏,檢測的難度使得使用C/C++編程語言的應用開發產生問題。

介紹:

動態分配、回收內存是C/C++編程語言一個最強的特點,但是中國哲學家孫(Sun Tzu,我不知道是誰?那位知道?)指出,最強的同時也是最弱的。這句話對C/C++應用來說非常正確,在內存處理出錯的地方通常就是BUGS產生的地方。一個最敏感和難檢測的BUG就是內存泄漏-沒有把前邊分配的內存成功釋放,一個小的內存泄漏可能不需要太注意,但是程序泄漏大塊內存,或者漸增式的泄漏內存可能引起的現象是:先是性能低下,再就是引起復雜的內存耗盡錯誤。最壞的是,一個內存泄漏程序可能用完了如此多的內存以至于引起其他的程序出錯,留給用戶的是不能知道錯誤到底來自哪里。另外,一個看上去無害的內存泄漏可能是另一個問題的先兆。幸運的是VC++DEBUGERCRT庫提供了一組有效的檢測和定位內存泄漏的工具。本文描述如何使用這些工具有效和系統的排除內存泄漏。

 

啟動內存泄漏檢測:

主要的檢測工具是DEBUGERCRT堆除錯函數。要使除錯函數生效,必須要在你的程序中包含以下幾個語句:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

并且這些#include 語句必須按上邊給出的順序使用。如果你改變了順序,可能導致使用的函數工作不正常。包含crtdbg.h的作用是用mallocfree函數的debug版本(_malloc_dbg _free_dbg)來替換他們,他們能跟蹤內存分配和回收。這個替換僅僅是在debug狀態下生效,Relese版本中還是使用普通的mallocfree函數。

上面的#define語句使用crt堆函數相應的debug版本來替換正常的堆函數。這個語句不是必需的,但是沒有他,你可能會失去一些有用的內存泄漏信息。

你一旦在你的程序中增加了以上的語句,你可以通過在程序中增加_CrtDumpMemoryLeaks();函數來輸出內存泄漏信息。

當你在debuger下運行你的程序時,_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的內容。

如果定義了_CRTDBG_MAP_ALLOC ,輸出信息還包含當前泄漏內存是在那個文件中被分配的定位信息。文件名后圓括弧中的數字是行數。如果你雙擊這行信息,
C:\PROGRAM FILES\VISUAL STUDIO\MyProjects\leaktest\leaktest.cpp(20) : {18}
   normal block at 0x00780E80, 64 bytes long.
光標就會跳轉到原文件中分配這個內存的行前。選擇Output中的題是行,按F4能達到同樣的效果。

 使用Using _CrtSetDbgFlag
 
如果你的程序的退出點只有一個的話,調用_CrtDumpMemoryLeaks將是非常容易。但是,如果你的程序有多個退出點話會是什么樣一個情況?如果不想在每個退出點都調用_CrtDumpMemoryLeaks,你可以在程序的開始包含以下調用:
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
這個語句會在你的程序結束時自動調用_CrtDumpMemoryLeaks,但是你必須象前邊提到的那樣設置_CRTDBG_ALLOC_MEM_DF _CRTDBG_LEAK_CHECK_DF這兩個標志位。

 介紹一下內存塊的類型:
 
就象前面指出的,一個內存泄漏信息指出每個內存泄漏塊的類型為普通、客戶端或者CRT型。在實際程序中,普通型和客戶端型式最常見的類型。
 
普通型內存塊是你的程序平常分配的內存類型。
 
客戶端型內存塊是MFC程序給需要析構的對象分配的內存塊。MFCnew操作可以選擇普通型或客戶端型中合適的一種作為將要被創建的對象的內存塊類型。
 CRT
內存塊是CRT庫為自己使用而分配的內存塊。CRT在處理自己的釋放內存操作時使用這些塊,所以在內存泄漏報告中這種類型并不常見,除非發生嚴重異常(例如:CRT庫出錯)。
 
還有兩種類型你在內存泄漏信息中看不到:
 
自由塊,它是已經被釋放的內存塊;
 
忽略塊,它是已經被特殊標示的內存塊。

 設置CRT報告的格式:
 
在默認情況下,_CrtDumpMemoryLeaks輸出的內存泄漏信息就象前邊描述的那樣。你可以使用_CrtSetReportMode讓這些輸出信息輸出到其他地方。如果你使用一個庫,它可能要使輸出信息到其他的地方,在這種情況下,你可以使用_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );語句使輸出信息重新定位到Output窗口。

 根據內存分配編號設置斷點:
 
內存泄漏報告中的文件名和行數告訴你內存泄漏的位置,但是知道內存泄漏位置不是總是能找到問題所在。在一個運行的程序中一個內存分配操作可能被調用多次,但是內存泄漏可能只發生在其中的某次操作中。為了確認問題所在,你除了知道泄漏的位置之外,你還必須要知道發生泄漏的條件。內存分配編號使得解決這個問題成為可能。這個數字就在文件名、行數之后的大括弧內。例如,在上面的輸出中“18”就是內存分配編號,它的意思是你程序中的內存泄漏發生在第18次分配操作中。
 CRT
庫對正在運行程序中所有的內存塊分配進行計數,包括自身的內存分配,或者其他庫(象MFC)。一個對象的分配編號是n表示第n個對象被分配,但是它可能并不表示第N個對象通過代碼被分配(在大多數情況下它們并不相同)。
 
你可以根據內存分配編號在內存被分配的位置設置斷點。先在程序開始部分附近設置一個斷點,當你的程序在斷點處停止后,你可以通過QuickWatch對話框或者Watch窗口來設置內存分配斷點。在Watch窗口中的Name列中輸入_crtBreakAlloc,如果你使用的是多線程DLL版本的CRT庫的話你必須包含上下文轉換 {,,msvcrtd.dll}_crtBreakAlloc。完成后按回車,debugger處理這次調用,并且把返回值顯示在Value列中。如果你沒有設置內存分配斷點的話返回值是-1。在Value列中輸入你想設置的分配數,例如18
 
你在自己感興趣的內存分配位置設置斷點后,你可以繼續debugging。細心的運行你的程序在相同的條件下,這樣才能保證內存分配的順序不致發生變化。當程序在特定的內存分配處停下來后, 你可以查看Call 窗口和其他的debugger信息來分析此次內存分配的條件。如果有必要你可以繼續運行程序,看一看這個對象有什么變化,或許可以得知為什么內存沒有被正確的釋放。
 
盡管這個操作非常容易,但是如果你高興的話也可以在代碼中設置斷點。在代碼中增加一行代碼_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把程序分成兩半分別使用上述方法來檢測內存泄漏,這樣就是使用二分法來檢查內存泄漏。。、47

posted on 2008-12-11 12:12 thronds 閱讀(479) 評論(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>
            99国产精品私拍| 99精品热视频| 欧美黄色小视频| 久久综合一区二区| 久久成人精品无人区| 久久久久久97三级| 欧美a一区二区| 欧美午夜在线观看| 国产美女一区二区| 亚洲第一网站| 亚洲网址在线| 久久夜色精品国产欧美乱| 欧美jjzz| 亚洲人成在线免费观看| 亚洲毛片一区二区| 午夜视频在线观看一区| 久久手机免费观看| 欧美日韩午夜| 在线免费一区三区| 亚洲午夜电影在线观看| 久久黄色级2电影| 最近看过的日韩成人| 亚洲在线免费观看| 欧美激情视频网站| 国产欧美日韩麻豆91| 亚洲久久一区| 久久久久久尹人网香蕉| 亚洲乱码国产乱码精品精可以看| 性8sex亚洲区入口| 欧美日本高清视频| 国产午夜精品一区二区三区视频| 亚洲国产一区二区三区青草影视| 午夜视频在线观看一区二区三区| 欧美肥婆在线| 欧美一区二区三区在线看 | 久久久久综合一区二区三区| 欧美日韩精品二区| 亚洲电影网站| 久久精品一区二区三区不卡牛牛| 亚洲三级影院| 久久综合九色| 在线成人www免费观看视频| 一区二区三区国产精华| 久久精品在线视频| 亚洲一区二区三区免费观看 | 国产精品不卡在线| 亚洲久久视频| 亚洲国产裸拍裸体视频在线观看乱了| 午夜欧美不卡精品aaaaa| 欧美午夜精品一区二区三区| 日韩视频免费在线| 亚洲国产第一| 欧美国产日韩二区| 亚洲精品在线视频| 91久久夜色精品国产九色| 欧美成人一品| 99国产精品视频免费观看| 亚洲国产毛片完整版| 欧美成人一品| 一区二区三区精品视频| 日韩亚洲视频在线| 国产精品第十页| 午夜国产精品视频免费体验区| 日韩一区二区精品葵司在线| 欧美日韩一区三区| 亚洲欧美日韩在线高清直播| 亚洲一区二区三区四区五区午夜| 国产精品久久久久久久久免费桃花| 亚洲一二三区精品| 亚洲欧美日韩一区在线| 国产一在线精品一区在线观看| 久久久精品五月天| 久久久噜噜噜久久中文字免| 亚洲国产精品www| 亚洲靠逼com| 国产精品蜜臀在线观看| 久久久国产视频91| 蜜桃久久av一区| 国产精品99久久久久久有的能看| 亚洲一区免费看| 樱桃成人精品视频在线播放| 亚洲韩日在线| 国产精品中文字幕欧美| 麻豆成人在线| 欧美日韩亚洲不卡| 久久免费国产精品| 欧美日韩国产综合视频在线观看| 羞羞视频在线观看欧美| 久久深夜福利免费观看| 一本久道久久综合婷婷鲸鱼| 午夜欧美大尺度福利影院在线看| 亚洲国产美女久久久久 | 欧美高清视频在线观看| 亚洲午夜一二三区视频| 欧美在线一二三区| 99精品国产福利在线观看免费| 亚洲一区二区三区乱码aⅴ蜜桃女| 在线视频国产日韩| 亚洲午夜精品一区二区三区他趣| 国语自产精品视频在线看抢先版结局 | 欧美日韩情趣电影| 性久久久久久久| 欧美激情精品久久久久| 久久精品伊人| 国产精品日韩一区| 亚洲国产欧美久久| 狠狠做深爱婷婷久久综合一区| 99精品黄色片免费大全| 亚洲国产精品美女| 午夜在线视频观看日韩17c| 一区二区三区高清| 美国十次成人| 毛片av中文字幕一区二区| 国产精品实拍| 国产精品99久久99久久久二8| 亚洲国产成人tv| 久久精品视频在线免费观看| 午夜亚洲伦理| 国产精品久久久久久久久久ktv| 亚洲国产欧美另类丝袜| 亚洲国产精品视频一区| 久久精品一本久久99精品| 欧美在线综合| 国产乱码精品一区二区三区五月婷| 亚洲精品一区二区在线| 日韩午夜电影av| 欧美另类综合| 亚洲精品美女在线观看| 亚洲精品裸体| 欧美激情在线狂野欧美精品| 亚洲国产va精品久久久不卡综合| 在线观看一区二区视频| 久久精品系列| 欧美大胆成人| 亚洲精品自在久久| 欧美日韩mp4| 一区二区电影免费观看| 亚洲午夜一二三区视频| 国产精品嫩草影院一区二区| 在线一区观看| 性伦欧美刺激片在线观看| 国产老肥熟一区二区三区| 亚洲免费视频中文字幕| 久久久999精品免费| 激情欧美日韩一区| 欧美aⅴ一区二区三区视频| 亚洲精品自在在线观看| 亚洲女性裸体视频| 国产欧美日韩亚洲精品| 久久精品国产综合| 亚洲激情在线播放| 亚洲欧美日韩第一区| 国产日韩精品在线| 久久这里只精品最新地址| 亚洲精选视频在线| 亚洲欧美日韩一区二区三区在线观看 | 亚洲欧洲av一区二区| 国产欧美一区二区视频| 久久久999精品免费| 亚洲电影在线观看| 亚洲婷婷免费| 亚洲午夜激情网站| 国产精品国产三级欧美二区| 亚洲性xxxx| 久久久噜噜噜| 亚洲美女中文字幕| 国产精品亚洲网站| 久久夜色精品国产亚洲aⅴ| 亚洲精品国产欧美| 久久riav二区三区| 亚洲精品美女在线| 国产精品专区一| 免费久久99精品国产自在现线| 在线亚洲免费| 欧美国产日韩一区二区三区| 在线视频精品一区| 韩国亚洲精品| 欧美三级视频在线播放| 久久久久久91香蕉国产| 一区二区三区.www| 欧美国产高清| 欧美一区二区在线免费播放| 亚洲精品少妇| 一区在线电影| 国产精自产拍久久久久久蜜| 欧美精品在线一区二区| 久久精品女人| 亚洲免费一区二区| 99国产精品99久久久久久| 欧美国产一区二区| 久久国产加勒比精品无码| 在线视频日本亚洲性| 亚洲高清中文字幕| 国产一区视频观看| 国产精品香蕉在线观看| 欧美日韩一区二区欧美激情| 欧美国产日韩精品| 欧美成人精品一区| 免费视频一区二区三区在线观看| 欧美一区二视频|