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

Lyt
posts - 16,comments - 61,trackbacks - 0

 在編程中經常涉及到內存管理,于是便希望有個內存檢測器來幫助我們debug。我們想檢測內存泄漏,就必須記錄程序中的內存分配和釋放情況,同時我們也希望能記錄內存分配代碼所在行號和位置,也就是我們需要重載以下四個全局函數:

void* operator new(size_t Size, char* FileName, int LineNum);
void* operator new[](size_t Size, char* FileName, int LineNum);
void operator delete(void* Object);
void operator delete[](void* Object);

下面將描述如何實現一個簡單的內存檢測器

1.獲得內存分配代碼所在行號和位置

我們需要將缺省的全局new operator替換為帶有文件名和行號的版本,代碼如下:

#define new new(__FILE__, __LINE__ )

2.建立記錄內存分配和釋放情況的數據結構NewList

NewList中記錄了內存分配代碼所在行號、位置、內存分配后獲得指針與大小。由于我們想記錄整個程序中內存分配和釋放情況,于是應實例化一個NewList全局對象NewRecord。

注意:全局對象應放在cpp中,如果放在.h中,.h文件又被多個文件include,于是會出現重定義

3.重載new和delete那四個全局函數

new:(1)分配內存,如果失敗了拋出異常 (2)記錄相關數據 (3)返回分配所得指針

注意在重載operator new[]時Size為0的情況,這時我們當Size=1;

delete :(1)找到相關數據并刪除 (2)釋放內存

void* operator new(size_t Size, char* FileName, int LineNum)
{
    
if (Size==(size_t)0) Size=1;
    
void* Result=::operator new(Size);
    
if (!Result) throw bad_alloc();
    
else
    
{
        NewListNode Temp(Result, Size, FileName, LineNum);
        NewRecord.Add(Temp);
        
return Result;
    }

}


void* operator new[](size_t Size, char* FileName, int LineNum)
{
    
if (Size==(size_t)0) Size=1;
    
void* Result=::operator new[](Size);
    
if (!Result) throw bad_alloc();
    
else
    
{
        NewListNode Temp(Result, Size, FileName, LineNum);
        NewRecord.Add(Temp);
        
return Result;
    }

}


void operator delete(void* Object)
{
    
if (!Object) return;
    NewRecord.Remove(Object);
    free(Object);
}


void operator delete[](void* Object)
{
    
if (!Object) return;
    NewRecord.Remove(Object); 
    free(Object);
}

4.如何打印出內存泄漏的有關信息

對于打印信息我們會有各種各樣不同的要求,譬如輸出到控制臺,輸出到文件,同時輸出到控制臺跟文件等。每一種情況都實現一個函數顯然不可行,為了應付這種情況,我們可以考慮如下數據結構:

class Print{};
class PrintToConsole : public Print{}; 

5.如何使用

(1)讓所有代碼都#include "DebugNew.h",如果有的代碼包含而有的代碼不包含,內存分配與釋放信息也就記錄不準確了。

(2)此代碼無法處理多線程的情況

6.使用效果

#include "DebugNew.h"
#include 
<stdlib.h>
#include 
<iostream>
#include 
<conio.h>

using namespace std; 
    
int main(int argc , char* argv[])
{
    
new int;
    Check();
    _getch();
    
return 0;
}

#include "DebugNew.h"
#include 
<stdlib.h>
#include 
<iostream>
#include 
<conio.h>

using namespace std; 
    
int main(int argc , char* argv[])
{
    
int* p=new int;
    delete p;
    Check();
    _getch();
    
return 0;
}

DebugNew.h

 1#ifndef DEBUGNEW_H
 2#define DEBUGNEW_H
 3
 4#include <iostream>
 5#include <stdlib.h>
 6#include "Link.h"
 7#include "Print.h"
 8
 9using namespace std;
10
11class NewListNode
12{
13public:
14    void* Object; //內存分配后獲得的指針
15    size_t Size; //內存分配的大小
16    char* FileName; //內存分配代碼所在文件位置
17    int LineNum; //內存分配代碼所在行號
18
19    NewListNode();
20    NewListNode(void* Buffer, size_t s, char* File, int Line);
21    NewListNode(const NewListNode& Temp);
22}
;
23
24class NewList
25{
26public:
27    Link<NewListNode> Data;
28
29    bool IsEmpty();
30    void Add(const NewListNode& Temp);
31    void Remove(void* Object);
32    void Check();
33}
;
34
35extern void* operator new(size_t Size, char* FileName, int LineNum);
36extern void* operator new[](size_t Size, char* FileName, int LineNum);
37extern void operator delete(void* Object);
38extern void operator delete[](void* Object);
39
40extern void Check();
41extern NewList NewRecord;
42
43#define new new(__FILE__, __LINE__ )
44#endif

 

DebugNew.cpp

  1#include "DebugNew.h"
  2#undef new
  3
  4NewListNode::NewListNode()
  5{
  6    Object=0;
  7    FileName=0;
  8}

  9
 10NewListNode::NewListNode(void* Buffer, size_t s, char* File, int Line)
 11{
 12    Object=Buffer;
 13    Size=s;
 14    FileName=File;
 15    LineNum=Line;
 16}

 17
 18NewListNode::NewListNode(const NewListNode& Temp)
 19{
 20    FileName=Temp.FileName;
 21    LineNum=Temp.LineNum;
 22    Object=Temp.Object;
 23    Size=Temp.Size;
 24}

 25
 26bool NewList::IsEmpty()
 27{
 28    if (Data.GetHead()) return false;
 29    else return true;
 30}

 31
 32void NewList::Add(const NewListNode& Temp)
 33{
 34    Data.AddLast()->Data=Temp;
 35}

 36
 37void NewList::Remove(void* Object)
 38{
 39    Node<NewListNode>* Temp=Data.GetHead();
 40    while (Temp)
 41    {
 42        if (Temp->Data.Object==Object)
 43        {
 44            Data.Delete(Temp);
 45            return;
 46        }

 47        Temp=Temp->Next;
 48    }

 49}

 50
 51void NewList::Check()
 52{
 53    PrintToConsole Printer;
 54    if (!IsEmpty())
 55    {
 56        Printer.Writeln("存在內存泄漏");
 57        Printer.Writeln("Line\tSize\tPath");
 58        Printer.WriteLine();
 59        Node<NewListNode>* Temp=Data.GetHead();
 60        while (Temp)
 61        {
 62            char Line[20];
 63            itoa(Temp->Data.LineNum, Line, 10);
 64            Printer.Write(Line);
 65            Printer.Write("\t");
 66            char s[200];
 67            itoa(Temp->Data.Size, s, 10);
 68            Printer.Write(s);
 69            Printer.Write("\t");
 70            Printer.Write(Temp->Data.FileName);
 71            Printer.Write("\t");
 72            Temp=Temp->Next;
 73        }

 74    }

 75    else Printer.Writeln("不存在內存泄漏");
 76}

 77
 78NewList NewRecord;
 79
 80void* operator new(size_t Size, char* FileName, int LineNum)
 81{
 82    if (Size==(size_t)0) Size=1;
 83    void* Result=::operator new(Size);
 84    if (!Result) throw bad_alloc();
 85    else
 86    {
 87        NewListNode Temp(Result, Size, FileName, LineNum);
 88        NewRecord.Add(Temp);
 89        return Result;
 90    }

 91}

 92
 93void* operator new[](size_t Size, char* FileName, int LineNum)
 94{
 95    if (Size==(size_t)0) Size=1;
 96    void* Result=::operator new[](Size);
 97    if (!Result) throw bad_alloc();
 98    else
 99    {
100        NewListNode Temp(Result, Size, FileName, LineNum);
101        NewRecord.Add(Temp);
102        return Result;
103    }

104}

105
106void operator delete(void* Object)
107{
108    if (!Object) return;
109    NewRecord.Remove(Object);
110    free(Object);
111}

112
113void operator delete[](void* Object)
114{
115    if (!Object) return;
116    NewRecord.Remove(Object); 
117    free(Object);
118}

119
120void Check()
121{
122    NewRecord.Check();
123}

 

Print.h

 1#ifndef PRINT_H
 2#define PRINT_H
 3
 4#include <stdlib.h>
 5#include <iostream>
 6
 7using namespace std;
 8
 9class Print
10{
11public:
12    virtual ~Print();    
13}
;
14
15class PrintToConsole : public Print
16{
17public:
18    virtual ~PrintToConsole();
19    virtual void Write(char* String);
20    virtual void Writeln(char* String);
21    virtual void WriteLine();
22}

23
24#endif

 

Print.cpp

 1#include "Print.h"
 2
 3Print:: ~Print()
 4{
 5}

 6
 7PrintToConsole::~PrintToConsole()
 8{
 9}

10
11void PrintToConsole::Write(char* String)
12{
13    if (String) cout<<String;
14}

15
16void PrintToConsole::Writeln(char* String)
17{
18    if (String) cout<<String<<endl;
19    else cout<<endl;
20}

21    
22void PrintToConsole::WriteLine()
23{
24    cout<<"-------------------------------------------------------------------------------"<<endl;
25}
posted on 2009-03-25 01:56 Lyt 閱讀(3253) 評論(2)  編輯 收藏 引用 所屬分類: 其他

FeedBack:
# re: 一個簡單的內存泄漏檢測器
2009-03-25 02:00 | 陳梓瀚(vczh)
1:你的delete用的是free,你要么用operator delete,要么用malloc分配內存。
2:PrintToConsole Printer;這樣是不對的,別人沒辦法將他自己的Printer傳給你。  回復  更多評論
  
# re: 一個簡單的內存泄漏檢測器
2009-03-27 19:20 | 路過
簡單就用標準庫直接帶的就好了啊
#include <crtdbg.h>
#define DEBUG_NEW new(_NORMAL_BLOCK ,__FILE__, __LINE__)
  回復  更多評論
  

只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美日韩一二三四五区| 性18欧美另类| 欧美在线视频观看| 欧美一区二区三区视频免费播放| 亚洲在线视频网站| 欧美一区三区二区在线观看| 欧美影片第一页| 久久久av网站| 亚洲丁香婷深爱综合| 亚洲欧洲在线视频| 亚洲一区bb| 欧美中文在线字幕| 欧美精品啪啪| 国产一区99| 一本久久综合亚洲鲁鲁| 欧美在线视频免费| 欧美激情一区| 亚洲免费在线播放| 久久亚洲综合色一区二区三区| 久久午夜视频| 亚洲经典三级| 午夜精品久久久久久久久久久久| 久久久久久**毛片大全| 欧美日韩一区免费| 国内精品视频在线播放| 中文国产成人精品| 久久色在线播放| 亚洲免费av网站| 久久久精品一区| 国产精品久久久久久久久久久久| 精品91久久久久| 亚洲欧美日韩精品久久奇米色影视 | 亚洲欧洲一区二区三区在线观看 | 亚洲毛片视频| 久久人人爽人人爽爽久久| 亚洲精品国产视频| 狂野欧美激情性xxxx| 国产欧美一区二区三区久久| 亚洲美女精品成人在线视频| 久久综合久久久久88| 亚洲宅男天堂在线观看无病毒| 欧美大片在线观看| 亚洲大胆人体视频| 久久婷婷久久| 欧美在线一区二区三区| 国产九色精品成人porny| 一区二区三区四区国产| 亚洲国产精品久久久| 久久久久99| 黄色成人在线网址| 久久久精品久久久久| 午夜精品在线观看| 国产日韩欧美制服另类| 校园激情久久| 午夜精品久久久久久久99黑人| 欧美午夜久久| 亚洲欧美在线磁力| 亚洲午夜久久久久久久久电影院| 欧美剧在线免费观看网站| 亚洲精品无人区| 亚洲国产综合在线看不卡| 欧美成人性生活| 在线亚洲伦理| 中文亚洲免费| 国产日韩在线亚洲字幕中文| 欧美一区二区三区免费看| 亚洲影院色无极综合| 国产精品捆绑调教| 久久成人这里只有精品| 欧美中文字幕在线| 亚洲人成网站在线观看播放| 欧美好骚综合网| 欧美日韩另类丝袜其他| 亚洲欧美一区二区激情| 欧美综合二区| 亚洲欧美视频在线观看视频| 欧美在线3区| 欧美日韩成人激情| 夜夜嗨av一区二区三区网页| 亚洲精品免费电影| 国产精品国产自产拍高清av王其| 羞羞色国产精品| 久久av二区| 日韩小视频在线观看专区| 99视频精品免费观看| 国产精品视频一区二区高潮| 久久久精品网| 欧美久久成人| 久久亚洲捆绑美女| 欧美日韩不卡合集视频| 欧美淫片网站| 欧美国产日韩二区| 欧美一区二区三区视频在线| 久久这里有精品15一区二区三区 | 欧美理论大片| 久久动漫亚洲| 欧美久久一区| 久久九九99| 欧美日韩日日骚| 久久亚洲国产精品一区二区| 欧美日韩视频一区二区| 久久国产精品黑丝| 欧美日韩伦理在线免费| 久久久久一区二区三区四区| 欧美日韩国产三级| 免费观看30秒视频久久| 国产精品久久久久国产精品日日| 嫩草国产精品入口| 国产精品综合色区在线观看| 亚洲二区精品| 国内久久婷婷综合| 国产精品99久久久久久久久久久久 | 久热re这里精品视频在线6| 午夜欧美不卡精品aaaaa| 欧美激情欧美激情在线五月| 久久久精品午夜少妇| 国产精品私人影院| 一本色道久久| 一二三区精品福利视频| 免费日本视频一区| 毛片一区二区| 国产综合亚洲精品一区二| 亚洲特级片在线| 亚洲一区日韩在线| 欧美日韩三区| 99国内精品| 在线一区亚洲| 欧美性猛交xxxx免费看久久久| 亚洲高清在线| 洋洋av久久久久久久一区| 麻豆精品在线观看| 亚洲电影在线播放| 亚洲一区二区毛片| 欧美精品成人在线| 亚洲激情在线激情| 亚洲精品一二区| 你懂的亚洲视频| 欧美高清在线视频| 亚洲国产婷婷综合在线精品| 免费观看成人www动漫视频| 欧美二区视频| 日韩性生活视频| 欧美日韩午夜剧场| 洋洋av久久久久久久一区| 亚洲综合大片69999| 国产精品自在线| 久久全国免费视频| 亚洲国产精品久久久久久女王| 亚洲免费成人av| 欧美天天视频| 欧美一区二区三区日韩| 麻豆成人综合网| 亚洲巨乳在线| 国产精品亚洲а∨天堂免在线| 亚洲欧美一区二区三区极速播放| 久久精品欧美| 亚洲日韩第九十九页| 欧美日韩中文字幕| 欧美怡红院视频| 亚洲二区精品| 欧美在线综合视频| 亚洲国产精品久久久久秋霞不卡 | 亚洲主播在线观看| 国产一区二区三区自拍| 噜噜噜在线观看免费视频日韩| 亚洲国产日韩美| 欧美亚洲视频| 亚洲精品国产精品乱码不99按摩| 欧美特黄一区| 久久成人人人人精品欧| 91久久精品国产| 欧美中在线观看| 亚洲日韩欧美视频一区| 国产欧美日本一区二区三区| 免费永久网站黄欧美| 亚洲小说欧美另类社区| 欧美激情免费在线| 性久久久久久久| 亚洲精品影院在线观看| 国产视频欧美视频| 欧美人体xx| 久久综合色综合88| 亚洲欧美一区二区视频| 亚洲激情av| 免费日韩一区二区| 欧美在线免费播放| 日韩天堂在线视频| 亚洲第一毛片| 国产欧美在线观看| 欧美日韩免费网站| 免费久久99精品国产自| 欧美一区二区女人| 国产精品99久久99久久久二8| 亚洲高清在线视频| 免费久久久一本精品久久区| 欧美在线综合| 午夜在线一区| 亚洲欧美一区二区三区在线| 99精品视频免费全部在线| 亚洲国产精品一区在线观看不卡|