小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

重載全局new/delete實現(xiàn)內(nèi)存檢測

 quasiceo 2012-12-11

重載全局new/delete實現(xiàn)內(nèi)存檢測

分類: C/C++ 1264人閱讀 評論(2) 收藏 舉報

下面介紹用重載new/delete運算符的方式來實現(xiàn)一個簡單的內(nèi)存泄露檢測工具,基本思想是重載全局new/delete運算符,被檢測代碼調(diào)用newdelete運算符時就會調(diào)用重載過的operator newoperator delete,在重載的operator new里和operator delete里記錄下內(nèi)存申請和釋放信息,從而判斷內(nèi)存使用情況。

下面一步步介紹它的實現(xiàn)!

1、  全局new/delete的重載

先看一下重載new/delete的規(guī)則:

重載的operator new的參數(shù)個數(shù)任意,但第一個參數(shù)必須是size_t類型的,返回值必須是void*。重載operator delete只允許有一個參數(shù),且是void*型。

當然,不光要重載operator new operator delete, 還要重載operator new [], operator delete [],更多operator newoperator delete重載的內(nèi)容參考《Effective C++

重載的new/delete, new[]/delete[]代碼如下:

void * operator new (size_t size){

if(0 == size){

        return 0;

}

void *p = malloc(size);

return p;

}

 

void * operator new [](size_t size){

return operator new(size);

}

 

void operator delete (void * pointer){

if(0 != pointer){

free(pointer);

}

}

 

void operator delete[](void * pointer){

       operator delete(pointer);

}

 

2、  __FILE__, __LINE__記錄new的位置

為了找到內(nèi)存泄露的元兇,我要記錄下每一處new所在的文件名和所在行。于是再次重載了operator new

void * operator new (size_t size, const char* file, const size_t line);

void * operator new [](size_t size, const char* file, const size_t line);

為了避免編譯時出現(xiàn)warning C4291(沒有與operator new(unsigned int,const char *,const unsigned int) 匹配的delete),又重載了

void operator delete (void * pointer, const char* file, const size_t line);

void operator delete[](void * pointer, const char* file, const size_t line);

              盡管我知道它沒用。

我想到了用系統(tǒng)提供的__FILE__ __LINE__宏獲取當前文件名與行號,我試圖把__FILE__ __LINE__直接填到operator newoperator new[]函數(shù)體里邊,然后把函數(shù)置成inline,結(jié)果都輸出的是重載operator newoperator new[]的文件和函數(shù)體printf函數(shù)所在行。然后又試了將operator new的缺省參數(shù)設為__FILE__ __LINE__結(jié)果依然,于是想到了用宏定義。

先看看MFC里的做法,MFC為了調(diào)試方便,對new進行了宏定義:

#define new DEBUG_NEW

#define DEBUG_NEW new(THIS_FILE, __LINE__)

 

這里我借用MFC的做法,我也用宏定義:

void * operator new (size_t size, const char* file, const size_t line)

void * operator new [](size_t size, const char* file, const size_t line);

#define MC_NEW new(__FILE__, __LINE__)

#define new MC_NEW

 

 

3、  malloc/free new/delete替換

為了便于統(tǒng)計malloc/free信息,也用宏定義的方法處理:

#define malloc(s) ((void*)new unsigned char[s])

#define free(p)   (delete [] (char*)(p));

 

4、  在數(shù)據(jù)結(jié)構(gòu)里存儲內(nèi)存使用情況。

            下面寫一個用于存儲new/delete中內(nèi)存信息的數(shù)據(jù)結(jié)構(gòu),可以使用鏈表,也可以使用哈希表,這里選用哈希表,寫一個CHash類。

代碼略。

 

5、  為了保證CHash在所有對象析構(gòu)執(zhí)行完之后再銷毀,應該將CHash放在全局存儲區(qū),將其設成static類型,另外,如果有多個static,還需要注意放置的順序。

 

到這里這個簡易的內(nèi)存泄露檢測工具完成了,但目前還不能用于多線程。

查看評論
2樓 hzyong_c 2011-01-20 17:53發(fā)表 [回復]
我的理解是這樣的:
這 樣做的目的是用戶調(diào)用new的時候最終調(diào)用的是new(THIS_FILE, __LINE__) 。編譯器把new(THIS_FILE, __LINE__) 看成是個是個整體,不會將new(THIS_FILE, __LINE__) 中的“new”分開來用new(THIS_FILE, __LINE__)取代,所以不會造成無限循環(huán)
1樓 shenyan008 2011-01-19 16:53發(fā)表 [回復]
問個問題:
#define new DEBUG_NEW

#define DEBUG_NEW new(THIS_FILE, __LINE__)

這么define不會死循環(huán)嗎?

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多