1. 程式人生 > 實用技巧 >C++記憶體管理知識總結<一 >——<記憶體部件介紹及使用>

C++記憶體管理知識總結<一 >——<記憶體部件介紹及使用>

 在講記憶體之前,咱先說一下記憶體分配方式,下面百度了兩張圖:

具體詳細介紹我就不說了,網上很多,接下來進行咱們得主題,本章主要介紹C++語言本身為我們提供的記憶體相關的使用工具

前言

  首先我們先說一下什麼是記憶體管理,記憶體管理都要幹什麼,記憶體管理用的就是記憶體池的概念來管理記憶體,就幹兩件事,一個是節省空間(new一塊記憶體頭和尾都附帶一個cookies佔8個位元組)另一個是提升分配速度,現在我們用的STL很方便,我們從來不用關心記憶體的分配,其實STL裡面有一個allocator,是它幫我們進行了記憶體管理。

一、C++ memory primitives

  C++ 應用程式使用記憶體的途徑方式如下:

當然我們不推薦直接使用最底層O.S.API(作業系統的記憶體呼叫API)的函式,因為越低階的函式跟作業系統的繫結就越密切,程式移植性就會越低,所以幾乎沒人直接使用這麼低階的函式,我們所探討的只是CRT這一層之上的工具情況,基礎工具比較如下:

1、new/delete背後的故事

  new的背後一般有如下3步,分配空間、型別轉換、呼叫建構函式,如下所示:

  delete背後經歷了呼叫解構函式、釋放記憶體的動作

注意:不能直接呼叫建構函式(除了new裡面之外),但是可以呼叫解構函式

2、array new/array delete背後的故事

  對陣列的操作我們需要中括號[]以告訴編譯器我們現在要new一個數組,所以這個中括號相當於一個標識一樣,同樣,delete的時候,我們也要加上中括號[],同樣是為了告訴編譯器釋放的是一個數組,如果釋放的時候沒有加上中括號[],編譯器就會以為要釋放的是一個object而不是陣列,就會造成記憶體洩漏

注意:因為所有的記憶體分配操作都會歸一到malloc/free上面來,而malloc/free幾乎在所有的平臺上實現都是一致的,都會在頭附帶一個cookie,這個cookie記錄了當前這一塊記憶體的資訊,後面delete的時候就知道大小了

多說一點題外話:

  • 如果我們設計的類有指標,那麼對於陣列來說一定要帶中括號[],如果沒有指標(也就是解構函式沒有用,啥也不做)那麼不帶中括號通常也沒有影響,但是對於好的程式設計習慣我們一定要遵守陣列的規定,還是帶上中括號比較好

2.1 array new使用

下圖有幾個要點:

  • array new的構造順序和解構函式整好是相反的
  • placement new的用法(後面介紹)不會建立,它是在已建立好的記憶體去呼叫建構函式(也就是說這種方式是唯一的一個
    在new之外由使用者主動呼叫建構函式的方法)

  

3、cookie的基本介紹

  如下圖所示,我們在申請記憶體的時候編譯器會給記憶體帶上cookie,它實際儲存的是這整塊記憶體的資訊(然後還要按照16的倍數進行位元組填充),下圖的上下61h就是上下cookie,黃色的部分Debugger header是debug模式下才會有的,pad 12byte是進行16位元組倍數調整時進行的填充,而實際編譯器給我們的記憶體地址(指標)是裡面的資料部分(圖中int部分);

注意:這裡接著前面提到過的陣列delete,如果不是物件(比如上圖int)沒有解構函式,那麼加不加中括號[]都無所謂,但是如果是物件,new[]之後記憶體的佈局會變如下圖會多一個3,則析構時必須加中括號[];

1 class Demo{
2 int a,b,c;
3 };