1. 程式人生 > 其它 >學習筆記--cpp記憶體管理(侯捷)

學習筆記--cpp記憶體管理(侯捷)

參考侯捷的視訊內容,總結的c++的記憶體管理知識。

cpp memory

1. 基礎知識

1.1 new

  • 用於動態建立一個物件。

    Person *p = new Person("name");
    
  • 編譯器將其轉換為以下步驟。

    1. 通過operator new 獲得一片記憶體的指標。
      • 實際上也是呼叫malloc。但保證不丟擲異常。
    2. 將該指標強制轉換成需要的指標Person *
    3. 通過指標呼叫該類的建構函式。
      • p->Person::Person("rui"),只有編譯器才可以這樣。

1.2 delete

  • 刪除new建立的記憶體。

    Person *p = new Person("name");
    ...
    delete p;
    
  • 編譯器將其轉換為以下步驟。

    1. 呼叫解構函式。p->~Person()
    2. operator delete該物件記憶體。
      • 實際上是呼叫free。但保證不丟擲異常。

1.3 array new/delete

  • 建立或刪除連續多個物件的記憶體。

    Person *p = new Person[3];
    //必須要有預設構造方法
    //無法由引數給予初值
    delete [] p;  //若不用[]可能會導致記憶體洩漏
    
  • delete記憶體洩漏,實際上是因為只調用了一次解構函式,而其他物件的解構函式沒有執行,最終導致洩漏。

    int *pi = new int[3];
    ...
    //下面語句效果與 delete [] pi; 相同 但建議加上
    //因為int沒有指向其他地方的記憶體,也沒有解構函式,所以不會造成記憶體洩漏
    delete pi;
    

1.4 replacement new

  • 定位new運算子,允許將物件分配到已經分配的記憶體中。需要包含new標頭檔案。

    • 等同於呼叫建構函式(編譯器行為)。
    • 需要顯式為每個物件呼叫解構函式(如果存在)
    • 應以建立順序相反的順序進行刪除,(晚建立的物件可能依賴於早建立的物件)
    • 當所有物件都被銷燬後才能釋放儲存這些物件的緩衝區。
    //緩衝區
    char *buffer = new char[12];
    
    int *p1 = new (buffer) int;
    int *p2 = new (buffer+4) int;
    delete [] buffer;     //直接釋放緩衝區,則會釋放p1,p2指向的資料
    
    char *buffer2 = new char(sizeof(string)*2);
    Person *person1 = new(buffer2) Person("rui1");
    Person *person2 = new(buffer2+sizeof(Person)) Person("mm");
    //顯式逆序呼叫解構函式,釋放名字存放記憶體
    person2->~Person();
    person1->~Person();
    //最後釋放緩衝區
    delete [] buffer2;
    

1.5 overload

  • 應用程式記憶體分配途徑
  • 容器類分配記憶體的途徑
  • 可以過載operator new/delete與operator new[] /dlelete[] ,詳細示例--AU:zedjay_