Overview
This introductory video draws memory diagrams to show how programs use memory, and how stack overflows and memory leaks happen. It uses C on purpose, as a microscope rather than a language to master, because C exposes memory behavior most directly. Memory is a row of equally sized cells, each with an address. A variable name is just a human label for one, so always look at the name, address and value together.
Key Points
- The stack is LIFO: each call pushes a frame for its local variables, removed automatically on return. But that data cannot outlive the function, and sizes are fixed at compile time.
mallocreserves heap memory at run time and returns its address, which a pointer on the stack holds. The data survives untilfreereleases it. A pointer still holding a freed address is dangling, so setting it to NULL is standard practice.- Python, Go and TypeScript code never calls
freebecause garbage collection automates it, reclaiming heap regions nothing points to. - A stack overflow happens when frames pile up past the stack’s limit (often just a few megabytes), as in recursion with no stop condition, and crashes immediately. A memory leak happens when the only pointer to unfreed heap memory is lost, slowly exhausting memory in long-running servers.
- Instead of the “a variable is a box” metaphor, which breaks down with pointers, the video recommends hand-drawing tables of addresses, values, types and sizes for both the stack and the heap.
Chapters
- 0:00 Introduction
- 0:25 Why C? / The goal of this video
- 0:57 Memory basics: addresses and cells
- 1:42 Two regions: the stack and the heap
- 1:57 The stack: the LIFO rule and code
- 3:34 How it cleans up automatically when a function ends
- 4:19 Two weaknesses of the stack
- 5:01 The heap: allocating freely with malloc
- 5:50 Today’s most important diagram (pointers and the heap)
- 6:44 Heap data outlives the function
- 7:28 Stack vs. heap recap
- 7:48 Releasing memory with free / dangling pointers
- 8:49 GC = automated free
- 9:21 Memory bug 1: stack overflow
- 10:45 Memory bug 2: memory leak
- 12:12 Comparing the two bugs
- 12:36 Drop the “a variable is a box” metaphor
- 13:15 How to draw memory tables by hand
- 14:59 Drawing tables for both the stack and the heap
- 15:24 Today’s summary
- 16:09 Three takeaways
概要
この入門動画では、メモリの図を一歩ずつ描きながら、プログラムがメモリをどう使うのか、そしてスタックオーバーフローとメモリリークがどう起きるのかを解説します。あえてC言語を使いますが、それは身につける言語としてではなく、メモリの動きがいちばんむき出しに見える「顕微鏡」としてです。メモリは同じ大きさの区画が1列に並んだもので、区画ごとにアドレスが振られています。変数名はその区画につけた人間用の名前にすぎないので、名前、アドレス、値の3つをいつもセットで見ることが大切です。
ポイント
- スタックは後入れ先出し(LIFO)です。関数を呼ぶたびにローカル変数を置くフレームが積まれ、関数が終わると自動で取り除かれます。ただし、そのデータは関数より長くは生きられず、大きさもコンパイル時に決めておく必要があります。
mallocは実行時にヒープのメモリを確保してそのアドレスを返し、スタック上のポインターがそれを持ちます。データはfreeで解放するまで残ります。解放済みのアドレスを指したままのポインターはダングリングポインターと呼ばれ危険なので、NULLを入れておくのが定石です。- PythonやGo、TypeScriptで
freeを書かないのは、ガベージコレクションがそれを自動化し、どこからも指されていないヒープの領域を回収しているからです。 - スタックオーバーフローは、止まる条件のない再帰などでフレームがスタックの上限(多くの環境でせいぜい数メガバイト)を超えて積み上がると起き、その場でクラッシュします。メモリリークは、解放していないヒープの領域を指す唯一のポインターが失われると起き、長時間動くサーバーのメモリをじわじわ食いつぶします。
- ポインターが出てくると破綻する「変数は箱」という比喩の代わりに、スタックとヒープの両方について、アドレス、値、型、サイズの表を手で書くことを勧めています。
チャプター
- 0:00 イントロ
- 0:25 なぜC言語を使うのか/この動画のゴール
- 0:57 メモリの基本:番地とセル
- 1:42 スタックとヒープ、2つの領域
- 1:57 スタック編:LIFOのルールとコード
- 3:34 関数終了で自動的に片付く仕組み
- 4:19 スタックの2つの弱点
- 5:01 ヒープ編:mallocで自由に確保
- 5:50 今日いちばん大事な図(ポインタとヒープ)
- 6:44 ヒープのデータは関数を超えて生き残る
- 7:28 スタック vs ヒープ 整理
- 7:48 freeで解放する/ダングリングポインタ
- 8:49 GC=自動化されたfree
- 9:21 メモリバグ①:スタックオーバーフロー
- 10:45 メモリバグ②:メモリリーク
- 12:12 2つのバグを比較
- 12:36 「変数は箱」という比喩をやめよう
- 13:15 メモリの表を手書きする方法
- 14:59 スタックとヒープ、両方の表を書く
- 15:24 今日のまとめ
- 16:09 持ち帰る3つのポイント