1. 程式人生 > >《C++高階程式設計》--有效的記憶體管理

《C++高階程式設計》--有效的記憶體管理

1、在程式中使用動態記憶體有兩個主要優點:
• 動態記憶體可以在不同的物件與函式之間共享
• 動態分配的記憶體空間大小可以在執行時確定

2、malloc、free和new、delete
• malloc和new的最大區別在於,new不僅會分配適當的空間,同時還會正確的構造物件;
class Foo;
Foo* myFoo=(Foo*)malloc(sizeof(Foo));
Foo* myOtherFoo=new Foo();
myFoo指向的物件並不是正確的物件,因為從來就沒有構造過一個Foo類的物件,malloc只是分配了足夠的記憶體空間來存放一個Foo類的物件;
myOtherFoo指向了一個Foo物件,因為new不僅分配了空間,並且還呼叫了Foo的建構函式。
• free和delete有類似的區別:使用free時,不會呼叫物件的解構函式;而delete卻會呼叫物件的解構函式,並且會正確清除該物件。
• 記憶體分配失敗時
如果new分配記憶體失敗,就意味著沒有足夠的記憶體空間來處理請求。new會丟擲一個異常,如果沒有異常處理的話,程式會停止。
還有另外一個new版本,它不會丟擲異常,而只是返回一個NULL:
int* ptr=new (nothrow) int;
雖然返回NULL不會讓程式退出,但是還是沒有很好的解決分配記憶體失敗的原因。
• 在C++中,不要使用realloc(),因為realloc會按新容量分配一個記憶體塊,把所有的舊資料按照“按位複製”移到新的位置,但是在C++中,使用者定義的物件不能很好的進行按位複製。
• 使用陣列語法宣告的陣列可以通過指標來訪問。把陣列傳遞給函式時,總是作為指標類傳遞的。

3、字串
• 在C語言中,字串表示為字元陣列,字串的最後一個字元是null字元'/0';常見的錯誤就是忘記給'/0'分配空間。
• 字串直接常量:cout<<"hello"<<endl;其中的"hello"就是字串直接常量,被看作const char* .
• 由於相容性可以呼叫string.c_str()來轉化成C風格的字串
• 將一個指標減去同類型的另一個指標,所得到的是兩個指標之間的元素個數,而不是兩個指標之間的絕對位元組數。

4、函式指標
函式指標根據引數型別和相容函式的返回型別來確定型別。使用函式指標最容易的方法是使用typedef來為一組給定特徵的函式賦一個型別名。
typedef bool (*funcPtr)(int,int);
funcPtr表示一個函式指標,該指標指向有兩個int引數且返回bool型別的任意函式。
函式名也可以代表函式的地址,還可以使用'&'來顯式的獲得函式的地址。

5、記憶體洩漏
記憶體洩漏的查詢可以使用專業的軟體包,也可以使用免費的valgrind.

6、智慧指標
智慧指標的概念源於這樣一個事實:如果把一切都放到棧中,這樣就可以避免與記憶體相關的大部分問題。因為在棧中一旦超出了作用域,就會
自動消除。
智慧指標的基本理論十分簡單,它是帶有一個關聯指標的物件,當智慧指標超出作用域的時候,會刪除關聯的指標。本質上講,
就是在一個基於棧的物件內部包裝一個堆物件。