Hi there 👋

大家好,我是 kf,平常喜歡利用做筆記的方式進行學習,最近在朋友的鼓勵下,開始把這些筆記整理出來與大家分享。如果有任何問題或建議,歡迎寄信到 kfwu1999@gmail.com 與我聯繫~

C++ 學習筆記 - std::shared_ptr

TL;DR 在上一篇 std::unique_ptr 的筆記中,已經簡短介紹智能指標的目的及用法。 在本篇筆記中,會逐步介紹 std::shared_ptr 的基本概念、用法、及簡易實作。 shared_ptr 簡介 與 unique_ptr 類似,shared_ptr 也是 C++11 中引入的一種智能指標,其目的是為了減少記憶體流失 (Memory Leak) 的風險。 與 unique_ptr 不同的地方在於,shared_ptr 允許多個 shared_ptr 實例指向同一塊動態記憶體。只有當最後一個 shared_ptr 被銷毀或重置後,該記憶體才會被釋放。 shared_ptr 會維護一個引用計數 (Reference Counting) 來管理記憶體的所有權。每當一個新的 shared_ptr 被創建或複製時,引用計數會增加;而當一個 shared_ptr 被銷毀或重置時,引用計數會減少。當引用計數歸零時,表示不再有指標指向該記憶體,此時記憶體將被自動釋放。 引用計數改變的情況 shared_ptr 的引用計數會在創建或被複製時增加,並在銷毀或重置時減少,主要會在以下幾種情況改變: 建構子 (Constructor) 解構子 (Destructor) 拷貝建構子 (Copy Constructor) 拷貝賦值運算子 (Copy Assignment Operator) 要注意的是,移動建構子 (Move Constructor) 及移動運算子 (Move Assignment Operator) 會有所有權轉移的步驟,在轉移後原本的指標會被設定為空指標,所以引用計數並不會改變。 成員變數與控制區塊 (Control Block) shared_ptr 本身除了指向動態記憶體區塊的指標之外,還有另外一個指標指向一個控制區塊 (Control Block),如下圖所示。其中控制區塊包含以下內容: 引用計數 弱引用計數: 此與 std::weak_ptr 有關,這邊先略過,會在後續筆記中做介紹 其他資料: 包含 Deletor 及 Allocator 等 而控制區塊會在以下幾種情況被建立:...

2024.09.04 · 5 min

C++ 學習筆記 - std::unique_ptr

TL;DR 在 C++ 中,std::unique_ptr 是一種很常用的智能指標 (Smart Pointer),其主要目的是自動管理動態記憶體,避免記憶體流失 (Memory Leak)。 在本篇筆記中,我會先由記憶體流失及智能指標 (Smart Pointer) 開始簡介,再逐步介紹 std::unique_ptr 的基本概念、用法、及簡易實作。 前言 記憶體流失簡介 如果要用一句話簡介記憶體流失 (Memory Leak) 的話,可以說:「當一個程式中分配的動態記憶體,在使用完畢後並未將其釋放,則會造成記憶體流失,減少可使用的主記憶體容量」。 如以下範例所示: 1 2 3 void func_with_memory_leak() { int* ptr = new int; } 在 func_with_memory_leak() 這個函式中,此函式分配了一塊記憶體,並用 ptr 指向這塊記憶體。當此函式結束後,分配的這個記憶體尚未進行釋放,由於 ptr 這個指標變數的生命週期結束了,導致沒有變數指向這塊已經分配好的記憶體,所以此塊記憶體在整個程式運行期間就沒有辦法進行釋放。 如果只有一小塊記憶體流失的話對整個程式的影響不大,但如果這類函式是放在迴圈當中 (如下列程式碼所示),或者是需要常常被呼叫的函式中,就很有可能因主記憶體的容量不夠,進而降低電腦的效能。 1 2 3 while (some_condition()) { func_with_memory_leak(); } 因此,若是分配出來的動態記憶體,在生命週期結束後,都要記得進行釋放,如下列程式碼所示: 1 2 3 4 5 6 7 void func_without_memory_leak() { int* ptr = new int; // ... delete ptr; } 另外,使用 exception 時也會造成記憶體流失的風險。如下列程式碼所示,當例外情況發生時,如果在記憶體釋放前拋出了例外,則記憶體可能會無法正常釋放,導致記憶體流失。...

2024.09.03 · 5 min