iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 3
0
Software Development

山姆大叔談 C++:從歷史談起,再給個定義—Modern C++ 解惑系列 第 3

DAY 2:指標是功能還是臭蟲?兼談 Smart Pointer(拜託不要翻成「聰明指標」)的必要性

這一篇要談的是程式語言界,人人聞之喪膽的「指標」以及「記憶體管理」,先抓出常見的問題,然後在之後的文章說明如何利用 Modern C++ 來減輕痛苦。開始前,我要跟讀者分享一個觀念。

面對指標該有的姿勢

指標雖難,但還沒難到認真學習而且投入心力,還學不會的地步。不要自己嚇自己,指標這種東西,下苦心,一定學得會,千萬不要還沒開始就放棄。

弄懂指標需要投入時間,初學者切勿躁進。學指標沒有捷徑,先搞懂基本觀念,多看優質程式碼,多練習,慢慢就會開竅。

不管外行人如何「污名化」指標,指標始終是 C++ 最重要的功能之一。懂得善用指標是專業 C++ 程式師的基本功。逃避不能成專業,若沒有面對指標的決心,不要戀棧,去學其他程式語言吧。

指標有什麼問題

指標讓程式師直接操控記憶體,功能強大,也因此帶來弄掛程式,甚至搞垮系統的高風險。指標相關的問題千百種,我列出幾個常見的難題:

  1. 沒有釋放記憶體
  2. 該由誰負責釋放索取的記憶體
  3. 弄錯對象
  4. 罄竹難書

底下程式碼示範典型的「記憶體洩漏」臭蟲:

  char* buffer = (char*)malloc(128);
  
  // ①
  if (something when wrong)
    return -1;
    
  memcpy(buffer, "123456", 6);
  // Do something...
  free(buffer);

位置 ① 若「invalid input」為真,函數直接跳離,導致 buffer 沒有被釋放(free)。你可能會說,這麼顯而易見的錯誤,不可能沒看出來吧?就是會!

另一個問題是,該由誰負責釋放記憶體?參考以下程式碼:

  Tea* tea = MakeTea();
  tea->DoSomething();
  delete tea; // ①

九成九,應該在 ① 那行刪除物件並釋放記憶體,但是,若 MakeTea() 回傳的是一個 Singleton 呢?若是,那麼呼叫端就不應該刪除該物件,而是由 MakeTea() 內部的機制管理。上述程式碼看不出這樣的意圖,可能一個不小心就生出一隻臭蟲。

還有一個常見的臭蟲是:使用 new 卻用 free() 釋放記憶體,或者相反。

C++11 加入了幾個好用的新組件,可用來對付指標以及記憶體管理。下一篇,我將介紹 std::unique_ptr,這個在幾乎不折損執行效能的情況下,提供物件以及記憶體管理的新方法。

延伸閱讀

TheChernoProject YouTube 頻道有一系列從入門到進階的 C++ 教學影片。關於指標,我建議看這片


上一篇
DAY 1:何謂「Modern C++」?從歷史談起,再給個定義——後篇
下一篇
DAY 3:只能死一次,不能鞭屍,談 std::unique_ptr<T>,卷一
系列文
山姆大叔談 C++:從歷史談起,再給個定義—Modern C++ 解惑26

尚未有邦友留言

立即登入留言