Module 2: Pointers & Memory Model
The core of C — what most courses get wrong
Lessons
| ID | Title | Duration |
|---|---|---|
| 2-1 | The Memory Model | 25 min |
| 2-2 | Pointers: &, *, and Arithmetic | 35 min |
| 2-3 | Arrays Are Pointers (Almost) | 30 min |
| 2-4 | const, NULL, and Dangling Pointers | 25 min |
| 2-5 | Double Pointers and void * | 30 min |
| 2-6 | Function Pointers | 25 min |
Project
| 2-proj | Project: Implement the String Library | 60 min |
Key Concepts
pointers, memory-layout, arrays, function-pointers, undefined-behaviour
Pedagogical Notes
The module teaches pointers through concrete address printing before introducing any abstraction. Lessons build in this order:
-
Memory regions first (2-1) — the mental model of where things live. Stack grows down, heap grows up, text is read-only. Students print addresses and observe the layout pattern. This grounds everything that follows.
-
Pointer syntax disambiguation (2-2) — the critical insight that
*means three different things (int *pdeclaration,*pdereference,*(p+n)arithmetic). The swap example is the canonical demonstration of why C uses pointers for mutation rather than reference semantics. -
Array decay (2-3) — the single most misunderstood rule. Arrays are not pointers, but they decay to one in almost every context. The
sizeofexception is the key diagnostic. String null-termination is the practical consequence. -
const and dangling (2-4) — two correctness tools.
conston a pointer parameter is a contract: “I won’t modify what you gave me.” A dangling pointer is the consequence of breaking the ownership rule — the memory outlived its contract. AddressSanitizer is introduced here. -
Double pointers and void* (2-5) — the pattern for modifying a pointer through a function, and the type-erased
void *that makesmalloc/qsortwork. The(ia > ib) - (ia < ib)comparator idiom avoids overflow. -
Function pointers (2-6) — functions are data at an address. Dispatch tables replace switch statements.
typedefis mandatory for readability. This is C’s mechanism for what OOP languages do with interfaces.
Common Traps
- sizeof after decay:
sizeof(arr)is 20 inside the declaring scope; pass it to a function and it becomes 8 (pointer size). Students must pass length separately. - strncpy does not null-terminate when truncation occurs — use
snprintfor thestr_ncopypattern from exercise 3.2 instead. - Writing to string literals:
char *p = "hello"; p[0] = 'X';is UB. String literals live in read-only text segment; always useconst char *. - Comparator overflow:
return a - bin aqsortcomparator overflows for large negative integers; the correct idiom is(a > b) - (a < b).
Key Code Examples
/* The * disambiguation — three different syntactic roles */
int x = 42;
int *p = &x; /* declaration: * is part of the type */
*p = 100; /* expression: * is dereference */
int *q = p + 1;/* arithmetic: p+1 skips sizeof(int) bytes *//* Array decay — where sizeof differs */
int arr[5];
int *p = arr; /* p == &arr[0] */
sizeof(arr); /* 20 — no decay */
sizeof(p); /* 8 — pointer size *//* void * — the generic pointer; qsort comparator pattern */
int cmp_int(const void *a, const void *b) {
int ia = *(const int *)a;
int ib = *(const int *)b;
return (ia > ib) - (ia < ib); /* never use ia - ib: overflows */
}Cross-Module Dependencies
- Requires m01-c-is-not-java — compilation model, C types, integer arithmetic
- Required by m03-dynamic-memory — malloc/free operate on
void *; ownership rules build directly on dangling pointer concepts from lesson 2-4 - Required by m04-structs-unions-bitfields — struct member access via
->is pointer dereference;offsetofuses pointer arithmetic - Referenced by m05-c-preprocessor —
container_ofmacro usesoffsetofand pointer arithmetic; introduced in ch03 Real-World Connection
PDF Status
- PDF ch03 (Pointers and the Memory Model) — Done
- Key Concepts: pointer syntax map table, arithmetic scaling, array decay, NULL, void *, double pointers, function pointer syntax
- Going Deeper: pointer provenance & strict aliasing, const-correctness & propagation, void * and the type system, function pointers
- Real-World: Linux kernel
container_of— intrusive linked list pattern - Exercises: 3.1 Map the address space, 3.2 str_ncopy, 3.3 void * arithmetic, 3.4 const-correct linked list
- Extended project: Implement the String Library (10 functions, ASan/UBSan clean)