← C++ Learning Path

C++ V2 · MEMORY MODEL · 53

Vector / Reference / Pointer:先分清楚 Value、Object、Alias 與 Address

C++ 最容易卡住的地方,不是 * 或 & 長得奇怪,而是把「值」「物件」「別名」「位址」「lifetime」混成同一件事。這一課先用 vector 與 pass-by-reference 建立安全直覺,再進 pointer。

Learning outcomes

1. Why now:前兩課的 Score 讀完就消失

for (...) {
    int score = 0;
    std::cin >> score;

    // after this iteration,
    // score object dies
}

如果要之後算平均、排序或套 bonus,你需要一個 container 保存多筆資料。

2. Mental model:Vector 擁有一段可變長度的 Element Sequence

#include 

std::vector scores = {
    80,
    90,
    100
};

scores.push_back(95);

vector 管理自己的元素 storage 與 size/capacity。你應透過它的 interface 使用,不需要自己手動 new/delete 一塊 raw array。

3. Worked Example A:Pass-by-Value 會複製 Argument Value

void addFive(
    int score
) {
    score += 5;
}

int score = 80;
addFive(score);

std::cout << score;
// 80

callee 的 score 是另一個 local object。

4. Worked Example B:Reference 是 Existing Object 的 Alias

void addFive(
    int& score
) {
    score += 5;
}

int score = 80;
addFive(score);

std::cout << score;
// 85
caller object:
score = 80

parameter:
int& score
→ alias same object

modify parameter
→ caller object becomes 85

5. const Reference:Borrow without Copy, but no Mutation

double average(
    const std::vector& scores
) {
    if (scores.empty()) {
        return 0.0;
    }

    int total = 0;

    for (int score : scores) {
        total += score;
    }

    return static_cast(
        total
    ) / scores.size();
}

這個 interface 表達兩件事:不複製整個 vector;function 不應修改 caller 的 vector。

6. Worked Example C:Range-for 裡 Reference 決定你改的是 Copy 還是 Element

for (int score : scores) {
    score += 5;
}
// vector unchanged
for (int& score : scores) {
    score += 5;
}
// vector elements changed

第一段每輪 score 是 copy;第二段是 element alias。

7. Pointer:保存 Address 的 Value

int score = 90;

int* ptr =
    &score;

std::cout << ptr;
std::cout << *ptr;
score object
  ↓ has address
&score
  ↓ store address
ptr
  ↓ dereference
*ptr
  ↓ access original object

8. Reference 與 Pointer 不等於 Ownership

int score = 90;

int& ref = score;
int* ptr = &score;

這兩個都可以指向/存取現有 object,但它們不自動回答「誰負責 object 的 lifetime」。Ownership 會到 135 再正式處理。

9. nullptr:沒有指向 Valid Object

int* ptr = nullptr;

if (ptr != nullptr) {
    std::cout << *ptr;
}

Dereference null pointer 是 undefined behavior。不要把「通常 crash」當成語言保證的唯一結果。

10. Dangling:Address 還留著,但 Object Lifetime 已結束

int* bad() {
    int local = 10;

    return &local;
}

function return 後 local object lifetime 結束;pointer 仍保存某個舊 address,但不再指向有效 object。

11. Vector Reallocation 也會影響 Reference / Pointer Validity

std::vector values = {
    1,
    2,
    3
};

int& first =
    values[0];

values.push_back(4);

// first may be invalidated
// if reallocation happened

Container mutation 可能使 references/pointers/iterators 失效。這不是 reference 語法本身壞,而是 underlying storage 移動。

12. Common mistakes

A. 把 & 當成固定一個意思

&x 是取 address;int& ref 是 reference declarator。

B. 把 raw pointer 當 ownership

它只保存 address-like value。

C. 以為 compile 成功代表 lifetime 安全

dangling 與 invalidation 常到 runtime 才爆。

D. 不必要地用 pointer

如果 value/reference 就能表達需求,不必為了「學 C++」硬用 raw pointer。

13. Debug evidence:Memory Bug 要先分類

null?
dangling?
out-of-bounds?
invalidated reference?
unexpected copy?
unexpected alias?

同樣是「值不對」,可能是 logic bug,也可能是 lifetime/alias 問題。先分類,再選工具。

14. Guided exercise:Bonus Function

void applyBonus(
    std::vector& scores,
    int bonus
) {
    // TODO
}

要求修改 caller vector;每筆最多 100。再把 parameter 改成 pass-by-value,觀察 caller 是否改變。

15. Independent exercise:Read-only Summary

寫:

int passedCount(
    const std::vector& scores
);

double average(
    const std::vector& scores
);

不允許修改 vector;empty case 要有明確 contract。

16. Challenge:Reference Invalidation Experiment

建立 vector、保存某元素 address/reference、持續 push_back,觀察 capacity 改變時 address 是否變化。不要把觀察結果誤寫成所有實作都固定的保證;重點是理解 reallocation 可能 invalidation。

Project checkpoint:CLI Grade Analyzer · Memory Model v3

stdin
  ↓
std::vector
  ├─ average(const&)
  ├─ passedCount(const&)
  └─ applyBonus(&)
        ↓
      mutate elements

下一課會把「程式碼本身」放回完整 build pipeline:compile / link / executable / process。

17. Vocabulary / Summary

18. Further reading

Knowledge check · Mastery

  1. 區分 value copy、reference alias、pointer address。
  2. 完成 bonus / summary functions。
  3. 解釋 dangling 與 vector invalidation 的 root cause。
  4. 完成頁面下方 C++ memory-trace practice。