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

首頁 > 編程 > C++ > 正文

C++對Crt內存泄漏檢測的分析

2020-02-24 14:35:35
字體:
來源:轉載
供稿:網友

C++對Crt內存泄漏檢測的分析,盡管這個概念已經讓人說爛了 ,小編在這里還是想簡單記錄一下, 以備以后查詢。


#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
#endif

?


int _tmain(int argc, _TCHAR* argv[])
{
??? char* p = new char();
??? char* pp = new char[10];
??? char* ppp = (char*)malloc(10);

??? _CrtDumpMemoryLeaks();

??? return 0;
}


主要原理是運用Crt 的內存調試功能, 通過宏替代默認的operator new, 讓它被下面版本替代:

?

?


void *__CRTDECL operator new(
??????? size_t cb,
??????? int nBlockUse,
??????? const char * szFileName,
??????? int nLine
??????? )
??????? _THROW1(_STD bad_alloc)
{
??? /* _nh_malloc_dbg already calls _heap_alloc_dbg in a loop and calls _callnewh
?????? if the allocation fails. If _callnewh returns (very likely because no
?????? new handlers have been installed by the user), _nh_malloc_dbg returns NULL.
???? */
??? void *res = _nh_malloc_dbg( cb, 1, nBlockUse, szFileName, nLine );

?

??? RTCCALLBACK(_RTC_Allocate_hook, (res, cb, 0));

??? /* if the allocation fails, we throw std::bad_alloc */
??? if (res == 0)
??? {
??????? static const std::bad_alloc nomem;
??????? _RAISE(nomem);
??? }

??? return res;
}


這樣Crt會把此次分配內存的文件名和行號以及大小等記錄下來,最后當調用用_CrtDumpMemoryLeaks(); 時如果還沒釋放就會打印出來。
結果如下:

?

?


Detected memory leaks!
Dumping objects ->
f:/test/memleakchecker/memleakchecker/memleakchecker.cpp(23) : {108} normal block at 0x0003A1A8, 10 bytes long.
?Data: CD CD CD CD CD CD CD CD CD CD
f:/test/memleakchecker/memleakchecker/memleakchecker.cpp(22) : {107} client block at 0x0003A160, subtype 0, 10 bytes long.
?Data: CD CD CD CD CD CD CD CD CD CD
f:/test/memleakchecker/memleakchecker/memleakchecker.cpp(21) : {106} client block at 0x0003A120, subtype 0, 1 bytes long.
?Data: 00
Object dump complete.


下面是一些注意事項:
(1) #define _CRTDBG_MAP_ALLOC 的作用
如果不定義這個宏, C方式的malloc泄露不會被記錄下來。

?

(2)數字{108} {107}的作用
表示第幾次分配, 你可以通過_CrtSetBreakAlloc程序運行到預定次數時暫停 ,比如


int _tmain(int argc, _TCHAR* argv[])
{
??? _CrtSetBreakAlloc(108);

?

??? char* p = new char();
??? char* pp = new char[10];
??? char* ppp = (char*)malloc(10);

??? _CrtDumpMemoryLeaks();

??? return 0;
}


(3)如果程序有多個出口或是有涉及到全局變量, 可以通過_CrtSetDbgFlag 設置標志讓程序退出時自動打印泄露 , 比如

?

?


int _tmain(int argc, _TCHAR* argv[])
{
??? _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

?

??? char* p = new char();
??? char* pp = new char[10];
??? char* ppp = (char*)malloc(10);

??? return 0;
}


(4)我們知道宏替代是最粗暴的方式, 所以盡量把下面new的替代宏放到每個Cpp里而不是放到一個通用的頭文件中, 實際上MFC也是這么做的

?

?


#ifdef _DEBUG
#define new DEBUG_CLIENTBLOCK
#endif


(5)上面的operator new只能照顧到最普通的new, 實際上operator new是有任意多種重載方式, 只需要確保第一個參數是表示大小。 比如下面的placement new就會編譯失敗, 因為宏替代后格式不符合要求了, 所以如果你的CPP用了非標準的new, 就不要加入new的檢測宏了。

?

?


#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
#endif


int _tmain(int argc, _TCHAR* argv[])
{
??? _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

??? char* p = new char();
??? char* pp = new char[10];
??? char* ppp = (char*)malloc(10);

??? char d;
??? char* p1 = new(&d) char('a');

??? return 0;
}


(6)因為STL里map內的tree用到了placement new,? 所以如果你這樣用會編譯失?。?/p>

?

?


#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
#endif

?

#include


你應該把 #include 放到 宏定義的前面。

?

(7) 如果你在宏 #define new DEBUG_CLIENTBLOCK 之后再聲明或定義 operator new函數, 都會因為宏替代而編譯失敗。
而STL的xdebug文件恰恰申明了operator new函數, 所以請確保new的替代宏放在所有include頭文件的最后, 尤其要放在STL頭文件的后面。


//MyClass.cpp
#include "myclass.h"
#include
#include

?

#ifdef _DEBUG
#define new DEBUG_CLIENTBLOCK
#endif

MyClass::MyClass()
{
??? char* p = new char('a');
}


(8)如果你覺得上面的這種new替代宏分散在各個CPP里太麻煩, 想把所有的東西放到一個通用頭文件里,請參考下面定義的方式:

?

?


//MemLeakChecker.h
#include
#include
//other STL file

?

#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
#endif


(9)簡單判斷某個獨立函數有沒有內存泄露可以用下面的方法:

?

?


class DbgMemLeak
{
??? _CrtMemState m_checkpoint;

?

public:
??? explicit DbgMemLeak()
??? {??
??????? _CrtMemCheckpoint(&m_checkpoint);
??? };

??? ~DbgMemLeak()
??? {
??????? _CrtMemState checkpoint;
??????? _CrtMemCheckpoint(&checkpoint);
??????? _CrtMemState diff;
??????? _CrtMemDifference(&diff, &m_checkpoint, &checkpoint);
??????? _CrtMemDumpStatistics(&diff);
??????? _CrtMemDumpAllObjectsSince(&diff);
??? };
};


int _tmain(int argc, _TCHAR* argv[])
{
??? DbgMemLeak check;
??? {
??????? char* p = new char();
??????? char* pp = new char[10];
??????? char* ppp = (char*)malloc(10);
??? }

??? return 0;
}


(10) 其實知道了原理, 自己寫一套C++內存泄露檢測也不難, 主要是重載operator new和operator delete, 可以把每次內存分配情況都記錄在一個Map里, delete時刪除記錄, 最后程序退出時把map里沒有delete的打印出來。 當然我們知道Crt在實現new時一般實際上調的是malloc, 而malloc可能又是調HeapAlloc,而HeapAlloc可能又是調用RtlAllocateHeap, 所以理論上我們可以在這些函數的任意一層攔截和記錄。但是如果你要實現自己的跨平臺內存泄露檢測,還是重載operator new吧,更多精彩內容,盡在武林技術頻道。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美性视频在线| 精品电影在线观看| 精品国产鲁一鲁一区二区张丽| 毛片精品免费在线观看| 久久精品在线播放| 91国内在线视频| 91精品视频免费观看| 在线国产精品视频| 亚洲人成自拍网站| 2021久久精品国产99国产精品| 欧美大肥婆大肥bbbbb| 日韩美女视频中文字幕| 亚洲欧美一区二区精品久久久| 欧美专区日韩视频| 色偷偷888欧美精品久久久| 亚洲一区二区中文字幕| 久久伊人精品天天| 精品中文字幕久久久久久| 国产区亚洲区欧美区| 国产亚洲精品美女久久久久| 欧美在线视频一区二区| 亚洲色图18p| 国产中文字幕亚洲| 这里只有精品在线播放| 亚洲精品小视频| 久久亚洲私人国产精品va| 亚洲缚视频在线观看| 久久网福利资源网站| 日本不卡免费高清视频| 亚洲一区999| 午夜免费在线观看精品视频| 欧美在线观看视频| 日韩美女毛茸茸| 国产日韩在线观看av| 久久免费福利视频| 国产黑人绿帽在线第一区| 91在线观看免费网站| 精品一区电影国产| 国产精品男人的天堂| 久久91亚洲精品中文字幕| 色综合导航网站| 国产精品综合不卡av| 色婷婷综合久久久久| 久久这里有精品视频| 91精品国产免费久久久久久| 亚洲欧美综合区自拍另类| 97国产精品免费视频| 国产91ⅴ在线精品免费观看| 久久久久成人精品| 欧美日韩一区二区免费视频| 久久久久中文字幕| 亚洲国产女人aaa毛片在线| 岛国精品视频在线播放| 日韩欧美国产中文字幕| 日本午夜在线亚洲.国产| 久久精品视频99| 亚洲国产天堂久久国产91| 97不卡在线视频| 91精品国产沙发| 欧美日产国产成人免费图片| 久久全球大尺度高清视频| 日韩美女毛茸茸| 91丨九色丨国产在线| 日韩av免费一区| 这里只有精品久久| 欧美日韩国产va另类| 久久久噜噜噜久久| 亚洲最新中文字幕| 久久久999精品视频| 91久久久国产精品| 亚洲欧美日韩久久久久久| 成人中文字幕在线观看| 97在线免费观看| 国产精品美女免费看| 91亚洲国产成人精品性色| 亚洲视频网站在线观看| 国产成人精品在线观看| 亚洲国产精品福利| 日韩成人中文字幕| 精品激情国产视频| 欧美性开放视频| 国内精品美女av在线播放| 欧美日韩国产综合视频在线观看中文| 久久久久亚洲精品成人网小说| 欧美在线免费观看| 亚洲欧美日韩一区二区在线| 欧美一级视频在线观看| 国产欧美日韩最新| 亚洲福利视频免费观看| 亚洲欧美在线免费| 亚洲人成在线电影| 国产精品福利在线观看| 国产精品久久久久久久久借妻| 国产伦精品免费视频| 中文字幕在线观看日韩| 欧美激情一二区| 97在线观看免费| 这里只有精品丝袜| 日韩欧美在线看| 成年人精品视频| 亚洲精品不卡在线| 欧美国产日韩一区二区三区| 日韩中文字幕不卡视频| 欧美黑人视频一区| 久久久这里只有精品视频| 亚洲欧美在线看| 色综合久久88色综合天天看泰| 国产精欧美一区二区三区| 久久人人爽人人爽人人片av高请| 黑人狂躁日本妞一区二区三区| 国产精品电影久久久久电影网| 91精品视频观看| 国产亚洲欧美aaaa| 色综合色综合网色综合| 精品国产91久久久久久| 精品av在线播放| 国产91久久婷婷一区二区| 成人中文字幕+乱码+中文字幕| 国产欧美在线视频| 国产亚洲欧洲高清| 日本sm极度另类视频| 深夜成人在线观看| 国产a∨精品一区二区三区不卡| 精品国产一区二区三区久久久狼| 久久久国产精彩视频美女艺术照福利| 欧美性做爰毛片| 亚洲激情视频网站| 国产成人一区二区在线| 久久精品国产亚洲7777| 亚洲精品一区久久久久久| 日韩视频―中文字幕| 午夜精品国产精品大乳美女| 九九九热精品免费视频观看网站| 亚洲精品一区二区在线| 亚洲性69xxxbbb| 日韩精品免费在线视频观看| 亚洲奶大毛多的老太婆| 懂色av一区二区三区| www.亚洲一区| 97在线视频免费播放| 九色精品免费永久在线| 91综合免费在线| 国产欧美精品在线播放| 狠狠色香婷婷久久亚洲精品| 亚洲欧美中文在线视频| 日韩久久精品成人| 亚洲欧洲日产国产网站| 视频直播国产精品| 亚洲精品网址在线观看| 欧美高清视频免费观看| 综合激情国产一区| 国产精品欧美日韩| 日韩av免费看网站| 国产精品久久97| 久久精品成人一区二区三区| 亚洲第一精品夜夜躁人人爽| 中文字幕久久久av一区| 亚洲国产精品久久久久久| 久久综合电影一区| 国产精品高潮呻吟久久av无限| 欧洲亚洲免费在线| 国产一区二区三区在线观看网站| 国产精品扒开腿做爽爽爽视频| 亚洲精品国产精品国自产在线|