C++ 智慧型指標(Smart Pointer):自動管理與回收記憶體

智慧型指標是 C++ 中一個常用的設計模式,它可以讓 C++ 的程式自行管理記憶體的配置與回收,避免記憶體洩漏等問題。


在 C/C++ 語言中,我們常常會使用指標(pointer)來配置或存取記憶體,一個指標變數儲存了記憶體的位址,而程式設計師就可以運用這個記憶體位址來做出各種變化,是一個非常好用的型別,甚至在某些複雜的應用上,如果沒有指標這項功能的話,可能會讓程式設計師不知道如何開發程式。

雖然指標對於 C/C++ 程式設計師而言非常重要,不過它難以管理的問題,也常常讓程式開發者頭痛,如果記憶體沒有配置得當,很容易造成懸置指標(dangling pointer)、空指標例外(null pointer exception)與記憶體洩漏(memory leak)等問題,嚴重的話會讓直接讓整個程式當掉、無法執行,而且記憶體配置與指標的問題在除錯上比較麻煩,編譯器並不會因為存取不對的記憶體位址而發出警告,必須要靠程式設計師自己小心的來處理。

假設有一段 C++ 程式碼如下:
Foo* foo = new Foo();
foo->Study();  // 如果這裡發生例外(exception)的話,
delete foo;    // 最後的記憶體將無法回收
如果在 Study() 函數中發生例外,讓程式提早跳出原有的執行順序的話,有可能就會造成這裡配置的記憶體永遠無法回收,直到程式執行結束為止,而這樣的問題就可以考慮以智慧型指標來解決。

智慧型指標(Smart Pointer)

智慧型指標其實就是把一般的指標包裝在 C++ 的物件之中,然後再加上一些記憶體管理的功能,而在使用上則跟一般的指標差不多,所以可以直接用來代替一般的指標。

智慧型指標的實作方式有許多種,這裡我們只是示範其中一種比較簡單的方式。其最基本的概念就是實作一個類別,將 *-> 這兩個運算子多載化(overloading),並在解構子(destructor)中加入記憶體回收的功能。
#include<iostream>
class Ptr {  // 實作智慧型指標的類別
  int *ptr;
  public:
  explicit Ptr(int *p = NULL) { ptr = p; }  // 將指標儲存起來
  ~Ptr() { delete(ptr); }  // 回收記憶體
  int &operator *() {  return *ptr; }  // 多載化 * 運算子
};
int main() {
  Ptr ptr(new int());
  *ptr = 4;
  cout << *ptr;
  // 智慧型指標會自動回收記憶體
  return 0;
}
這裏我們使用智慧型指標來管理記憶體,在動態配置的記憶體使用完之後,它就會自動回收沒有用的記憶體。這裡我們以基本的 int* 指標來示範實作的概念,實務上通常我們會改用泛型程式設計的方式,實作各種型別都可以用的智慧型指標。

由於智慧型指標已經是一個很普遍的技術了,有許多開放原始碼的函式庫都有提供這樣的功能,與其自己寫倒不如直接使用既有的函式庫,例如 boost 就有提供這樣的功能,另外在 C++ 11 的標準中也加入了 General-purpose smart pointers,所以如果現在要開發新的程式,直接使用這些資源會比較輕鬆。

參考資料:The Geek Stuff
本站已經搬家了,欲查看最新的文章,請至 G. T. Wang 新網站

1 則留言:

  1. Grosvenor Hotel Casino & Spa: Luxury Hotel in Israel - Air
    Grosvenor Hotel air jordan 18 retro varsity red clearance Casino & Spa is situated on the air jordan 18 retro yellow suede great site top level of air jordan 18 stockx online shop Israel's renowned Gold Coast and air jordan 18 retro yellow suede online site features over 2,000 guest rooms. Located in the jordan 18 white royal blue sale centre of

    回覆刪除