學習筆記--cpp記憶體管理(侯捷)
阿新 • • 發佈:2021-10-13
參考侯捷的視訊內容,總結的c++的記憶體管理知識。
cpp memory
1. 基礎知識
1.1 new
-
用於動態建立一個物件。
Person *p = new Person("name");
-
編譯器將其轉換為以下步驟。
- 通過
operator new
獲得一片記憶體的指標。- 實際上也是呼叫
malloc
。但保證不丟擲異常。
- 實際上也是呼叫
- 將該指標強制轉換成需要的指標
Person *
。 - 通過指標呼叫該類的建構函式。
p->Person::Person("rui")
,只有編譯器才可以這樣。
- 通過
1.2 delete
-
刪除
new
建立的記憶體。Person *p = new Person("name"); ... delete p;
-
編譯器將其轉換為以下步驟。
- 呼叫解構函式。
p->~Person()
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_