C++內存管理:new / delete 和 cookie


new 和 delete

C++的內存申請和釋放是通過 new 和 delete 實現的, 而new 和 delete 其實就是通過 malloc 和 free 實現的。

 

 

 

new 申請內存分為三個步驟:

  1. 調用 operator new 函數分配目標類型的內存大小,operator new 函數內部就是調用的 malloc 函數。
  2. 將申請得到的內存塊強制轉換為目標類型指針。
  3. 通過指針調用目標的構造函數(只有編譯器可以這樣直接調用構造函數)。

 

 

delete 釋放內存分為兩個步驟:

  1. 調用對象的析構函數。
  2. 調用 operator delete 函數釋放對象內存,operator delete 函數內部就是調用的 free 函數。

 

array new 和 array delete

array new 是申請多個對象的內存。

 

Cookie

通過 malloc 分配的內存,會在內存前后加上 cookie,以記錄內存分配的總大小,這里以包含三個 int 數據的 Demo 類為例:

 

 

上面 61h 存儲的就是內存塊的大小,其中最低位用於表示是否已分配(1表示已分配,0表示已回收),其中的 3 記錄了分配對象的數量。

當申請內存后,返回的指針指向數據開始處(00481c34),而使用 delete[] 釋放時,指針會指向00481c30,從而可以根據對象的數量調用相應次數的析構函數。如果使用 delete 釋放的話,它不會去00481c30地址獲取對象的長度,而是直接釋放00481c34位置處的對象。

所以,new[] 和 delete[] 需要配合使用,但是如果對象的類型是內置類型或者是無自定義的析構函數的類類型,是可以使用 delete 來釋放 new[] 對象的。否則使用 delete 來釋放對象的話,對象所分配的內存空間可以釋放,但是只會調用第一個對象的析構函數,可能導致內存泄漏。

 

 

 

 

對於 cookie,可以從運行速度和空間使用兩個方面去進行改進:

  1. 減少 malloc 的調用次數(雖然 malloc 的速度很快)。
  2. 每一個 new 的對象都會有上下兩個 cookie,可以預先申請一塊內存池,然后供對象實例化,這樣只會在這一整塊的內存池上下有 cookie,同時也可以減少 malloc 的調用次數。

      (關於內存池可以看下一篇文章 C++內存管理:簡易內存池的實現 

 

 

 

參考:

  1. C++內存管理(malloc和free中的cookie)
  2. C++內存分配之new與delete

  3. new和delete或new[]和delete[]為什么要配對使用?

  4. [c++]重新了解delete[]

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM