【讀書筆記】Effective C++(08)定製new和delete

作者:LogM

本文原載於 https://segmentfault.com/u/logm/articles,不允許轉載~

8. 定製new和delete

  • 8.1 條款49:瞭解new-handler的行爲

    • new-handler相當於new的異常處理函數。new申請內存發生異常,調用new-handler處理,處理完了之後繼續嘗試new,如果還是出錯,繼續調用new-handler,以此反覆。
    • //標準庫對於new-handler是這麼寫的:
      //new_handler被定義成一個函數指針
      //set_new_handler函數的參數是個指針,指向new無法分配足夠內存時應該調用的函數;
      //set_new_handler函數的返回值是個指針,指向set_new_handler之前設置的new_handler函數
      namespace std {
          typedef void (*new_handler)();
          new_handler set_new_handler(new_handler p) throw();
      }
      
      //可以這樣使用set_new_handler
      void oufOfMem()
      {
          std::cerr << "Unalbe to new\n";
          std::abort();
      }
      int main()
      {
          std::set_new_handler(outOfMem);
          int * pBigArray = new int[10000000000L];
      }
    • 一般來說,new-handler函數會做以下事情的某幾件:

      • a. 讓更多內存可被使用。使得再次嘗試new能成功。
      • b. 安裝另一個new-handler。使用更強力的new-handler處理。
      • c. 卸載new-handler。實在不行,卸載new-handler使new拋出異常。
      • d. 拋出bad_alloc的異常。
      • e. 退出程序。abort()或exit()。
  • 8.2 條款50:瞭解new和delete的合理替換時機

    • 這部分講的是:如果你覺得編譯器自帶的new和delete不好用,應該怎麼寫一個自定義的函數替換。
    • 作者自己也提到了,要自定義new和delete不是簡單寫個函數就好了,內存的申請和釋放會涉及到計算機體系架構中比較底層的東西,比如"內存對齊"。所以重頭開始寫new和delete是比較複雜的,可以買現成的商業產品,或者在開源代碼上修改。
  • 8.3 條款51:編寫new和delete時需要固守常規

    • 條款50已經說明了,自定義new和delete比較複雜,非必要不建議重寫。
    • 這部分講了自定義new和delete時需要注意的事項:

      • operator new應該內含一個無窮循環,並在其中嘗試分配內存,分配不了,調用new-handler。
      • operator new對0 bytes的內存申請,也需要正常返回指針。
      • operator delete應該在收到null指針時不做任何事。
  • 8.4 條款52:寫了placement new也要寫placement delete

    • Widget* pw = new Widget
      //這句話中總共有2個函數被調用:1.operator new分配內存;2.Widget的構造函數
      //當調用Widget構造函數發生異常時,需要delete掉第一步new出來的內存
      //如果使用C++自帶的new和delete,這個情況不需要用戶考慮;如果是自定義new和delete,需要用戶考慮
發佈了52 篇原創文章 · 獲贊 19 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章