1. 程式人生 > 其它 >Effective C++ 條款16~17

Effective C++ 條款16~17

Effective C++ 條款16:成對使用new和delete時要採取相同形式

我們先看下面兩行程式碼

std::string* stringArray = new std::string[100];
delete stringArray;

這裡我們先new了一個string陣列,然後又把這個陣列刪除了。但是delete沒有用[],發生了記憶體洩露。

這個記憶體洩露可能跟我們理解上有點偏差。首先我們new是100個string物件,如果單純的用delete,這100個物件所佔用的地址確實是被釋放掉了。

但是string裡面可是進行了動態記憶體分配的。換句話說,每個string裡面都是有一個指標。如果想安全的釋放每個string物件所佔用的記憶體,就必須呼叫string的解構函式。

不過遺憾的是,我們這裡是直接給delete。它會直接釋放這100個string物件,並不會呼叫每個物件的解構函式。

如果用delete[]就不同了,它會告訴編譯器,你將要釋放的是個陣列。請一個一個的delete他們。那當我們單獨delete一個string的時候,當然會呼叫它的解構函式。這樣才能避免記憶體洩漏。

Effective C++ 條款17:以獨立的語句將new出的物件置入智慧指標

考慮下面這段程式碼

// preliminary
int priority();
class Widget{};

// call function 'doSomething'
doSomething(shared_ptr<Widget>(new Widget), priority())

在執行呼叫語句的時候,編譯器需要考慮這三個步驟

  • new Widget
  • 呼叫priority方法
  • 將new出來的Widget臨時物件放入智慧指標
  • 呼叫doSomething

doSomething一定在最後執行。但是呼叫priority方法和將new出來的指標放入shared_ptr這兩個,也就是(2)和(3)的步驟是不確定的。

如果在呼叫priority方法時出錯了,程式崩潰或者丟擲異常了。那麼new Widget得到的指標就會成為野指標。那段記憶體就洩露了。

所以,以獨立的語句將newed物件儲存於智慧指標內。