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

隨筆-91  評論-137  文章-0  trackbacks-0
上一篇中我們已經實現了一個簡單的內存池,可以申請更大塊的內存塊來減少申請小塊內存塊時產生的內存碎片。

在本篇中,我們需要為其加入內存泄漏的檢測代碼,以此來檢測代碼編寫過程中的疏忽帶來的內存泄漏。(callstack的顯示暫時僅支持Windows)

一、內存泄漏檢測
首先,改寫obj和block結構,在obj中加入一個域released表示這個chunk是否被釋放
 1     struct obj
 2     {
 3 #ifdef _DEBUG
 4         bool      released;
 5 
 6 #if defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) // Only windows can get callstack
 7 #define CALLSTACK_MAX_DEPTH 30
 8         UINT_PTR  callStack[CALLSTACK_MAX_DEPTH];
 9         DWORD     dwCallStackDepth; // Real depth
10 #endif
11 
12 #endif
13         obj*      next;
14     };
15 
16     struct block
17     {
18         block*    next;
19         void*     data;
20 #ifdef _DEBUG
21         size_type size;
22 #if defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
23         UINT_PTR  callStack[CALLSTACK_MAX_DEPTH];
24         DWORD     dwCallStackDepth;
25 #endif
26 #endif
27     };
其中的callstack部分將在下一節中介紹

然后,我們增加一個結構
1 #ifdef _DEBUG
2     struct use
3     {
4         obj* data;
5         use* next;
6     };
7 #endif
其中data域指向了一塊分配出去的小內存塊,next域形成了一張鏈表。

然后,我們添加一個成員變量來保存這張鏈表,以及一個函數來將一個chunk插入這張鏈表
#ifdef _DEBUG
    use*      use_list;
#endif

#ifdef _DEBUG
inline void MemoryPool::addUseInfo(obj* ptr)
{
    use* p = (use*)malloc(sizeof(use));
    p->data = ptr;
    p->next = use_list;
    use_list = p;
}
#endif

然后,我們來改寫refill函數使其在分配內存塊時打上released標記,并將每個分配的內存塊記錄下來
 1 void* MemoryPool::refill(int i, void(*h)(size_type))
 2 {
 3     const int count = 20;
 4     const int preSize = (i + 1) * ALIGN + headerSize;
 5     char* p = (char*)malloc(preSize * count);
 6     while(p == 0)
 7     {
 8         h(preSize * count);
 9         p = (char*)malloc(preSize * count);
10     }
11     block* pBlock = (block*)malloc(sizeof(block));
12     while(pBlock == 0)
13     {
14         h(sizeof(block));
15         pBlock = (block*)malloc(sizeof(block));
16     }
17     pBlock->data = p;
18     pBlock->next = free_list;
19     free_list = pBlock;
20 
21     obj* current = (obj*)p;
22 #ifdef _DEBUG
23     addUseInfo(current);
24     current->released = false;
25 #endif
26     current = (obj*)((char*)current + preSize);
27     for(int j = 0; j < count - 1; ++j)
28     {
29 #ifdef _DEBUG
30         addUseInfo(current);
31         current->released = true;
32 #endif
33         current->next = chunk_list[i];
34         chunk_list[i] = current;
35         current = (obj*)((char*)current + preSize);
36     }
37     return (char*)p + headerSize;
38 }
其中的headerSize跟callstack有關,將在下一節中介紹。

當然,在deallocate時要將此內存塊的released標記打為true
 1 void MemoryPool::deallocate(void* p, size_type n)
 2 {
 3     if(p == 0) return;
 4     if(n > MAX_BYTES)
 5     {
 6         free(p);
 7         return;
 8     }
 9     const int i = INDEX(ROUND_UP(n));
10 #ifdef _DEBUG
11     p = (char*)p - (int)headerSize;
12     obj* ptr = reinterpret_cast<obj*>(p);
13     if (ptr->released) throw error<char*>("chunk has already released", __FILE__, __LINE__);
14     ptr->released = true;
15 #endif
16     reinterpret_cast<obj*>(p)->next = chunk_list[i];
17     chunk_list[i] = reinterpret_cast<obj*>(p);
18 }

OK,現在已經有模有樣了,可以松口氣了。接下來是最重要的部分,在MemoryPool析構時檢測這個Pool內的use_list中是否有chunk的released標記為true(內存泄漏了)
 1 MemoryPool::~MemoryPool()
 2 {
 3 #ifdef _DEBUG
 4     while (use_list)
 5     {
 6         use *ptr = use_list, *next = use_list->next;
 7         if (!ptr->data->released)
 8         {
 9             obj* pObj = ptr->data;
10             Console::SetColor(truefalsefalsetrue);
11             throw error<char*>("chunk leaked", __FILE__, __LINE__);
12         }
13         free(ptr);
14         use_list = next;
15     }
16 #endif
17     clear();
18 }
其實說來也容易,只需要檢測每個chunk的released標記是否為true就行了,而最后的clear函數是以前析構函數的代碼,用來釋放所有申請的block和大塊的chunk。

OK,現在我們已經可以檢測出沒有被deallocate的chunk了。

二、callstack
首先,我們先來看一個Windows API,“CaptureStackBackTrace”這個API通過傳入的一個數組來得到一組地址。當然有這個API并不夠,我們還需要知道是哪個文件的第幾行。“SymGetSymFromAddr64”這個API用來獲取某個地址對應的函數名,“SymGetLineFromAddr64”這個API則是用來獲取某個地址對應的文件名和行號的,這兩個函數的32位版本則是不帶64的。有了這些Windows API,我們就可以很輕松的獲取到當前函數的調用堆棧了,主要的功勞還是要歸功于Windows強大的dbghelp。

最后,完整的代碼你可以在http://code.google.com/p/qlanguage/中找到。
posted on 2013-01-19 20:09 lwch 閱讀(1977) 評論(0)  編輯 收藏 引用 所屬分類: STL
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            日韩一级黄色av| 有码中文亚洲精品| 亚洲免费人成在线视频观看| 欧美日韩天堂| 欧美国产日本| 午夜一级久久| 亚洲欧美成人网| 欧美一区在线直播| 久久国产精品黑丝| 麻豆精品一区二区综合av| 欧美18av| 国产区欧美区日韩区| 国产一区二区三区久久悠悠色av| 韩国精品在线观看| 99成人精品| 久久精彩视频| 亚洲国内自拍| 黄色精品一区二区| a4yy欧美一区二区三区| 亚洲欧美一区二区激情| 美日韩精品免费观看视频| 亚洲精品极品| 久久精品国产视频| 亚洲国产美女精品久久久久∴| 99视频+国产日韩欧美| 欧美一区=区| 欧美日韩一级大片网址| 一区二区三区无毛| 亚洲一区精品视频| 欧美成人精品不卡视频在线观看| 一区二区高清视频| 老鸭窝亚洲一区二区三区| 欧美性理论片在线观看片免费| 精品二区久久| 欧美与欧洲交xxxx免费观看| 亚洲国产日韩一区二区| 久久aⅴ国产欧美74aaa| 欧美午夜视频网站| 亚洲精品免费网站| 久久综合国产精品| 亚洲伊人观看| 欧美日韩国产影院| 久久久久久精| 国产农村妇女毛片精品久久麻豆 | 久久三级福利| 国产精品v欧美精品v日韩精品| 在线观看欧美精品| 久久久久www| 亚洲自拍电影| 欧美性片在线观看| 一本大道久久a久久精品综合| 美女黄毛**国产精品啪啪| 亚洲一区二区三区乱码aⅴ| 欧美日本中文字幕| av不卡在线| 亚洲电影免费在线 | 另类图片国产| 亚洲国产欧美日韩| 欧美一区二区三区视频免费| 亚洲精品一区二| 女人天堂亚洲aⅴ在线观看| 国语精品一区| 久久久亚洲国产美女国产盗摄| 午夜精品久久久久久久99黑人| 欧美视频观看一区| 亚洲午夜女主播在线直播| 91久久极品少妇xxxxⅹ软件| 男女激情久久| 亚洲欧洲日韩在线| 亚洲国产精品一区二区三区| 欧美国产第二页| 日韩网站在线观看| 亚洲毛片网站| 欧美香蕉大胸在线视频观看| 中国成人在线视频| 亚洲午夜激情| 国产一区二区福利| 欧美~级网站不卡| 欧美成人免费va影院高清| 99在线观看免费视频精品观看| 9l视频自拍蝌蚪9l视频成人| 欧美视频三区在线播放| 亚洲女性裸体视频| 欧美一级久久久| 最新高清无码专区| 亚洲精品视频在线观看网站 | 免费国产自线拍一欧美视频| 99ri日韩精品视频| 亚洲图中文字幕| 国产手机视频精品| 免费观看30秒视频久久| 欧美国产视频在线| 欧美在线电影| 欧美成人精品在线观看| 亚洲欧美一区二区精品久久久| 欧美一级视频| 99国产精品久久久久久久久久| 亚洲视频在线观看网站| 黄色在线成人| 一区二区三区www| 娇妻被交换粗又大又硬视频欧美| 亚洲精品乱码久久久久久日本蜜臀| 国产精品久久久久高潮| 欧美不卡高清| 国产久一道中文一区| 亚洲黄色av一区| 国产一区二区在线观看免费播放| 亚洲国产精品一区在线观看不卡| 国产三级欧美三级| 一区二区三区导航| 亚洲激情六月丁香| 性色av一区二区三区| 99av国产精品欲麻豆| 久久久精品五月天| 欧美一级久久久| 欧美日韩一区在线视频| 香蕉av777xxx色综合一区| 亚洲伊人一本大道中文字幕| 久久综合影音| 久久久久久综合| 国产精品尤物| 在线视频精品| 亚洲视频在线观看免费| 欧美大片在线观看| 欧美va日韩va| 在线免费观看日韩欧美| 亚洲免费在线| 午夜精品亚洲| 国产精品高精视频免费| 亚洲精品欧美日韩专区| 亚洲国产精品美女| 久久蜜臀精品av| 免费在线看一区| 亚洲成人在线免费| 久久这里只有| 欧美激情在线免费观看| 亚洲国产另类久久久精品极度| 久久久综合网站| 欧美成人精品三级在线观看| 136国产福利精品导航| 久久久激情视频| 欧美 日韩 国产在线| 最新中文字幕一区二区三区| 免费观看一区| 亚洲国产一区二区三区a毛片 | 亚洲综合不卡| 国产精品电影观看| 亚洲一区三区视频在线观看| 欧美一区二区高清| 国产午夜精品全部视频播放| 欧美一区二区视频免费观看| 看片网站欧美日韩| 亚洲大片精品永久免费| 欧美成人嫩草网站| 亚洲精品一二三| 午夜在线不卡| 激情懂色av一区av二区av| 久久久精品日韩欧美| 亚洲国产精品久久久久久女王| 一区二区三区精品视频| 国产精品免费aⅴ片在线观看| 亚洲欧美在线一区| 欧美xart系列高清| 在线亚洲观看| 国产自产在线视频一区| 美女亚洲精品| 在线亚洲欧美视频| 久久久久久久久久久成人| 亚洲夫妻自拍| 国产精品免费小视频| 久久视频一区二区| 日韩亚洲精品视频| 久久精品人人做人人综合 | 欧美第一黄网免费网站| 99亚洲伊人久久精品影院红桃| 欧美在线播放视频| 亚洲精品影视| 国产中文一区二区三区| 欧美激情一区二区三区四区| 午夜精品久久久久久99热| 亚洲高清毛片| 久久久免费av| 亚洲一区二区在线观看视频| 麻豆精品视频在线| 久久久久国产精品一区| 亚洲丰满在线| 国产视频精品xxxx| 欧美精品久久久久久久| 亚久久调教视频| 一本久久a久久免费精品不卡| 久久精品国产免费观看| 亚洲一区精品视频| 亚洲精品中文字| 激情五月综合色婷婷一区二区| 国产精品播放| 欧美日韩免费高清| 久久―日本道色综合久久| 午夜精品福利电影| 亚洲视频网在线直播| 亚洲精品乱码久久久久|