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

WisKeyのLullaby

huangwei.pro 『我失去了一只臂膀』「就睜開了一只眼睛」

  C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
  12 Posts :: 0 Stories :: 23 Comments :: 0 Trackbacks

公告

“我該走哪條路?”
“這取決于你要去哪里?!?br> “我只想能到某個地方?!?br> “只要你走的夠遠,你始終能到達那個地方?!?br>

Home: huangwei.pro
E-Mail: sir.huangwei [at] gmail.com
09.6 畢業于杭州電子科技大學
進入網易杭州研究院工作至今

常用鏈接

留言簿(1)

我參與的團隊

搜索

  •  

積分與排名

  • 積分 - 51753
  • 排名 - 447

最新評論

閱讀排行榜

評論排行榜

#

     摘要:   http://blog.huang-wei.com/2010/07/15/double-array-trie%ef%bc%88%e5%8f%8c%e6%95%b0%e7%bb%84%e5%ad%97%e5%85%b8%e6%a0%91%ef%bc%89/ Trie在ACM中已經十分普及,也是一種非常有效的索引結構,好處就不多說了。 它的本質就是一個確定的有限狀態自動機(DFA)...  閱讀全文
posted @ 2010-07-23 08:51 威士忌 閱讀(7514) | 評論 (1)編輯 收藏

http://blog.huang-wei.com/2010/07/18/%e9%87%8d%e8%bd%bdnewdelete%e5%ae%9e%e7%8e%b0%e5%86%85%e5%ad%98%e8%ae%a1%e6%95%b0/



 

有時為了統計內存使用,或檢測內存泄漏,重載全局的 new/delete 是一種比較簡易的實現方法。讓我們先來回顧下 new/delete 重載的相關內容吧。

技術篇

[::] new [placement] new-type-name [new-initializer]
[::] new [placement] ( type-name ) [new-initializer]
[::] delete cast-expression
[::] delete [ ] cast-expression

這里說明下,我們重載的是全局 new/delete,類 new/delete 和全局的有一些區別,在此就不細說了。

重載 operator new 的參數個數是可以任意的,只需要保證第一個參數為 size_t,其后的參數作為placement,返回類型為 void * 即可。
operator delete 的參數個數也可以是任意的,需保證第一個參數為 void *,返回類型為 void 即可。
一般的說,operator new/delete 的重載更像是函數的重載,而不是操作符的重載。

先來看看系統的new/delete都干了些啥事吧。

void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
        {       // try to allocate size bytes
        void *p;
        while ((p = malloc(size)) == 0)
                if (_callnewh(size) == 0)
                {       // report no memory
                static const std::bad_alloc nomem;
                _RAISE(nomem);
                }
        return (p);
        }
 
void *__CRTDECL operator new[](size_t count) _THROW1(std::bad_alloc)
    {   // try to allocate count bytes for an array
    return (operator new(count));
    }
void operator deletevoid * p )
{
    RTCCALLBACK(_RTC_Free_hook, (p, 0));
    free( p );
}
 
void operator delete[]( void * p )
{
    RTCCALLBACK(_RTC_Free_hook, (p, 0))
    operator delete(p);
}

看到這些CRT代碼,如何寫重載,估計你心里也已經有底了。其實CRT里還有好幾個版本的 new/delete 實現,有些是為兼容老版本,有些是Debug用的。

MFC里為調試方便,對new也進行過宏定義:

#define new DEBUG_NEW
#define DEBUG_NEW new(THIS_FILE, __LINE__)

new 的工作流程:

  1. 編譯器遇到 operator new 時,會去調用 type::operator new( sizeof( type ) ),如果該函數沒有沒定義,則調用 ::operator new( sizeof( type ) )。還有 placement 參數,會接在第一個參數之后。
  2. 分配內存空間,這時返回的指針指向的是一塊原始內存空間。
  3. 初始化對象,從上一步返回的地址開始初始化,系統會自動把 new-initializer 帶上,并調用相應的構造函數。
  4. 返回 new-type-name 或 type-name 類型的指針,用戶可以使用該指針訪問對象,該指針指向的地址也還是第2步返回的地址。

流程中還有些細節問題:

  1. 第1步中如果沒找到相應的函數怎么辦?
  2. sh!t,當然編譯會出錯羅。- -

  3. 第2步中分配內存失敗怎么辦?
  4. 空間不足導致內存分配失敗,可以返回 NULL,或者 throw std::bad_alloc,再或者你可以調用 set_new_handler來設置一個函數,此函數將在分配內存失敗時被調用。

  5. 第3步中,如果分配成功,而初始化對象失敗怎么辦?
  6. 如果使用 new 運算符的 placement 形式(除了帶分配大小還帶參數的形式),并且對象的構造函數引發異常,編譯器仍將生成調用 delete 運算符的代碼;但只有當存在與分配內存的 new 運算符的 placement 形式相匹配的 delete 運算符的 placement 形式時,編譯器才會這樣做。如果沒有實現,那可能就會造成內存泄漏。

關于內存管理的更多話題,可以進一步閱讀《Effective C++》

當然,有new就應該會有delete,在這兩者之間我們需要保存一些信息?,F在我只是想做統計,所以內存的占用數是必須被記錄的,在new時加上該值,delete時減去該值。
在申請空間時附加上一些信息域是一種較易實現的方法,當然你完全可以維護一個獨立的列表,記錄申請的空間,這樣的實現能容納更多的信息,適合查內存泄漏。

其實系統在new[]時,也會判斷申請的對象delete時是否需要調用析構函數(1、顯式的聲明了析構函數;2、擁有需要調用析構函數的類的成員;3、繼承自需要調用析構函數的類),如果是則會多申請4字節,保存分配的對象個數,并且返后的內存地址是實際申請得到的內存地址值加4后的結果。這也是為啥“對應的new和delete要采用相同的形式”的原因。

好像有點扯遠了,成了備忘帖了。- -

利用以上的知識,就夠我們實現內存計數了,so 開始動手實踐吧。

設計篇

其實我認為重載全局new/delete本身就不是一個不好的設計,這樣帶來了問題會變得復雜很多。

但是無奈,我不想改動現有的工程代碼,而且我需要統計元類型的內存分配。
理想中的設計是:

  1. 不允許重載全局operator new/delete。
  2. 使用allocator類(負責實現內存管理算法的類),可以重載或者說提供operator new/delete。
  3. 這個在STL的里有實現,為啥我不直接套用呢,因為不是所有工程都完全采用STL風格編碼,導致我只能用比較原始的方法實現。那如果遇到malloc/free呢?oh,sorry,我也無能為力了。索性C++開發人員使用new/delete來控制內存分配已經是常識了。

  4. operator new/delete應該有機會取得類型的元信息(如構造、析構函數、類名等),以便進行一些特殊處理(如提供debug調試信息、垃圾回收-自動完成析構等)。
  5. 如果這些信息都能獲取,OMG,那就太完美了,就能實現個強大的內存泄漏和內存管理工具。

我想實現的風格是盡可能的和普通的new/delete格式相似,并且需要能控制哪些內存分配需要被統計,哪些不要統計。存儲統計數據的變量不應是全局的,因為有時需要單獨測試某些類或模塊,所以這些統計數據應該是局部的,并可控制的。

我們可以利用 new 的 placement 來實現統計的控制,方法類似于 DEBUG_NEW 的宏定義。

比較棘手的是 delete,它的函數并沒有可傳入參數的形式。解決方法一,繼續附加信息,如magic num。解決方法二,使用全局變量控制。方法一的缺點是導致統計的內存開銷變大,而且magic num也有誤識別的可能;方法二的缺點是多線程競爭臨界資源,并且需要宏定義成函數或逗號表達式。

至于統計數據的局部化,在這方面,如果重載的不是全局new/delete,那會有更完美的解決方案??上КF在看來全局變量的使用在所難免了,但我們可以用個全局的指針,由他指向需要被統計的變量。

 1// op_new_delete.h
 2extern size_t* _mem_use_;
 3extern size_t _mem_tmp_;
 4#define SETPTR_MEM(p)    _mem_use_ = p
 5#define GETPTR_MEM        (_mem_use_ ? _mem_use_ : &_mem_tmp_)
 6#define GETCNT_MEM        *GETPTR_MEM
 7#define CLEARCNT_MEM(p)    SETPTR_MEM(p); GETCNT_MEM = 0
 8#define dbgnew            new(1)
 9#define dbgdel            delete
10void* operator new(size_t size, int flag);
11void* operator new[](size_t size, int flag);
12void operator delete(void* p);
13void operator delete[](void* p);

 1// op_new_delete.cpp
 2const size_t _magic_num_ = 0xF0F0AAAA;
 3const size_t _header_size_ = sizeof(size_t) * 2;
 4size_t* _mem_use_ = NULL;
 5size_t _mem_tmp_ = 0;
 6void* operator new( size_t size, int flag )
 7{
 8    if (size < 0) size = 0;
 9    if (flag) GETCNT_MEM += size, size += _header_size_;
10    else if (size == 0) size = 1;
11    void* p = NULL;
12    while (! p) p = ::malloc(size);
13    if (! flag) return p;
14    ((size_t*)p)[0= _magic_num_;
15    ((size_t*)p)[1= size - _header_size_;
16    return (void*)((size_t*)p + 2);
17}

18void* operator new[]( size_t size, int flag )
19{
20    return operator new(size, flag);
21}

22void operator delete(void* p)
23{
24    if (p == 0return;
25    if (_magic_num_ == ((size_t*)p)[-2]) {
26        GETCNT_MEM -= ((size_t*)p)[-1];
27        ::free((void*)((size_t*)p - 2));
28    }

29    else
30        ::free(p);
31}

32void operator delete[](void* p)
33{
34    operator delete(p);
35}

當然這樣在VC2005下會有難看的 C4291 warning,只要加上與 new 相同形式的 delete 函數即可。

先寫到這吧,有不正確或更完美解決方案,就請路人留言多踩踩吧,呵呵~

posted @ 2010-07-23 08:48 威士忌 閱讀(1326) | 評論 (0)編輯 收藏

僅列出標題
共2頁: 1 2 
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲国产天堂久久综合| 国内自拍亚洲| 艳妇臀荡乳欲伦亚洲一区| 亚洲第一视频网站| 久久躁日日躁aaaaxxxx| 久久精品视频导航| 久久亚洲春色中文字幕| 欧美凹凸一区二区三区视频| 亚洲第一久久影院| 亚洲国产日韩一区| 在线中文字幕一区| 欧美怡红院视频| 牛夜精品久久久久久久99黑人| 久久一区二区三区av| 欧美不卡在线视频| 欧美午夜在线观看| 狠狠综合久久av一区二区小说| 最新精品在线| 午夜精品久久久久久| 蜜臀va亚洲va欧美va天堂| 亚洲欧洲一区二区天堂久久| 亚洲在线成人精品| 久久亚洲私人国产精品va| 欧美日本在线观看| 国内不卡一区二区三区| 一本大道av伊人久久综合| 久久国产视频网| 亚洲国产精品高清久久久| 亚洲一区二区三区中文字幕| 久久亚洲精品一区二区| 国产精品美女久久久浪潮软件| 一区二区三区在线免费观看| 一区二区av| 欧美不卡视频一区| 亚洲欧美国产高清va在线播| 欧美精品在线视频观看| 亚洲第一天堂无码专区| 欧美在线播放| 亚洲人成人99网站| 久久国产精品99久久久久久老狼| 欧美日韩亚洲不卡| 亚洲高清成人| 久久国产手机看片| 一本大道久久a久久精二百| 久久久久久久999| 国产精品高潮呻吟久久av黑人| **性色生活片久久毛片| 欧美在线观看网址综合| 亚洲精品影院| 欧美国产日韩一区| 亚洲激情在线播放| 老司机精品视频网站| 午夜精品久久久久久久99水蜜桃| 欧美日韩国产精品专区| 日韩午夜免费视频| 亚洲激情第一页| 欧美xxx成人| 亚洲靠逼com| 亚洲国产裸拍裸体视频在线观看乱了| 久久久久九九视频| 一色屋精品亚洲香蕉网站| 久久精品国产2020观看福利| 亚洲免费在线观看| 国产免费观看久久| 久久国产精品久久精品国产| 午夜激情亚洲| 国产午夜精品全部视频播放| 欧美一区二区三区久久精品茉莉花 | 亚洲伊人观看| 欧美性猛交一区二区三区精品| 亚洲视频精选在线| 一区二区电影免费在线观看| 欧美亚洲成人精品| 香蕉久久夜色精品| 欧美一区久久| 在线视频成人| 亚洲日本电影在线| 国产精品国产三级国产aⅴ浪潮 | 亚洲国产毛片完整版| 欧美激情综合网| 中文日韩在线视频| 亚洲性夜色噜噜噜7777| 国产日韩欧美在线播放不卡| 久久夜色精品国产欧美乱| 美女网站久久| 亚洲尤物视频网| 欧美一区三区二区在线观看| 亚洲电影欧美电影有声小说| 亚洲精品在线观看视频| 麻豆国产va免费精品高清在线| 午夜在线视频观看日韩17c| 国产热re99久久6国产精品| 久久久久国内| 欧美激情中文字幕乱码免费| 欧美一级在线视频| 久久亚洲欧洲| 午夜电影亚洲| 免费亚洲婷婷| 香蕉免费一区二区三区在线观看 | 亚洲午夜高清视频| 亚洲永久在线| 亚洲韩国日本中文字幕| 日韩视频免费在线观看| 国产在线精品一区二区中文| 91久久黄色| 精品999久久久| 亚洲无吗在线| 日韩一级精品视频在线观看| 久久国产精彩视频| 亚洲一区欧美| 欧美精品二区| 欧美粗暴jizz性欧美20| 国产午夜精品理论片a级大结局| 亚洲全部视频| 在线精品视频一区二区| 亚洲在线黄色| 亚洲尤物在线| 欧美日韩免费观看中文| 免费高清在线视频一区·| 国产精品推荐精品| 日韩亚洲一区在线播放| 亚洲人成网站999久久久综合| 欧美在线观看一区二区三区| 亚洲欧美日韩国产一区二区| 欧美日韩高清区| 亚洲国产日韩一区二区| 亚洲国产天堂久久综合网| 久久久久久久久综合| 久久久久综合| 黄色综合网站| 久久久久九九九| 久久综合久久久| 国内精品久久久久久久果冻传媒| 亚洲欧美日韩一区二区| 亚洲午夜精品一区二区| 欧美久久精品午夜青青大伊人| 欧美黄色aa电影| 亚洲人成网站999久久久综合| 蜜桃久久av| 亚洲激情在线观看视频免费| 亚洲精品综合精品自拍| 欧美精选午夜久久久乱码6080| 91久久国产综合久久| 一本久久精品一区二区| 欧美日韩美女| 亚洲尤物在线视频观看| 久久久www免费人成黑人精品 | 亚洲视频播放| 国产精品久久久一区二区三区| 亚洲一级在线观看| 欧美在线视频在线播放完整版免费观看 | 欧美一区中文字幕| 国产精品视频一区二区三区| 一区二区三区免费看| 亚洲欧美综合v| 国产午夜精品视频| 久久亚洲私人国产精品va媚药| 欧美韩日一区二区| 一本色道久久99精品综合 | 欧美在线高清| 蜜臀av在线播放一区二区三区 | 久久久久久亚洲精品杨幂换脸| 国产麻豆视频精品| 久久精品一区二区三区中文字幕 | 亚洲国产成人91精品| 99v久久综合狠狠综合久久| 欧美日韩视频在线一区二区观看视频 | 久久成人国产| 亚洲国产欧美国产综合一区| 一本色道婷婷久久欧美| 国产精品私房写真福利视频 | 一区二区三区**美女毛片| 欧美一区二区三区另类| 亚洲第一久久影院| 欧美三级欧美一级| 久久av一区二区| 亚洲精品自在久久| 久久精品国产免费看久久精品| 91久久精品国产91久久性色tv| 国产精品v欧美精品v日韩精品| 欧美在线视频网站| 亚洲精品视频免费在线观看| 久久久久88色偷偷免费| 一道本一区二区| 黄色成人av网| 国产精品女同互慰在线看| 毛片av中文字幕一区二区| 亚洲自拍偷拍一区| 91久久久国产精品| 久久亚洲精品一区| 亚洲欧美日韩精品久久亚洲区| 亚洲国产精品视频| 国产午夜精品理论片a级探花| 欧美日韩国产精品成人| 久久综合伊人77777| 香蕉久久夜色精品国产| 一本久久知道综合久久| 欧美11—12娇小xxxx| 欧美影院久久久| 亚洲综合不卡|