thecodex.expert · The Codex Family of Knowledge
Track 3 — Advanced

C: Advanced

Five lessons: pointer arithmetic, undefined behaviour and tools, dynamic data structures, function pointers, and POSIX.

🕐 ~4 hours5 lessonsC17 / POSIX

Lessons

Lesson 1

Pointer arithmetic and multi-level pointers

p+n advances by n elements, pointer subtraction, void* and casting, char** (argv pattern), and const pointers vs pointer to const.

What to look for:

  • p + n advances by n * sizeof(*p) bytes — type-aware arithmetic
  • void* is a generic pointer — must cast before dereferencing
  • const int *p: pointer to const int (can't modify value through p)
  • int *const p: const pointer to int (can't change where p points)
🕑 50 min
Lesson 2

Undefined behaviour and sanitisers

What UB is, the six most dangerous forms (buffer overflow, UAF, signed overflow, uninit reads), -Wall -Wextra, ASan, UBSan, and valgrind.

Prerequisite: Practitioner Track

What to look for:

  • UB is not "implementation-defined" — the compiler makes no guarantee at all
  • -fsanitize=address,undefined: the most impactful flag for catching bugs during development
  • Signed overflow is UB; unsigned overflow is defined (wraps modulo 2^n)
  • ASan has ~2–5x slowdown — suitable for debug builds; not production
🕑 50 min
Lesson 3

Linked lists and dynamic data structures

Singly linked list (node_new, prepend, append, search, free_list), doubly linked list basics, and memory ownership contracts.

Prerequisite: Lesson 1

What to look for:

  • Each node is a heap allocation: malloc(sizeof(Node)) — free every node on cleanup
  • Self-referential struct: use struct Node (not typedef) in the pointer field definition
  • Ownership: whoever allocates is responsible for freeing — document this clearly
  • free_list walks the list freeing each node — save next before freeing current
🕑 50 min
Lesson 4

Function pointers and the vtable pattern

Function pointer declaration, typedef for fn pointer types, passing callbacks to qsort, dispatch tables, and the Linux kernel vtable pattern.

Prerequisite: Lesson 3

What to look for:

  • typedef int (*Comparator)(const void*, const void*) — cleaner fn pointer type
  • qsort(arr, n, sizeof(int), cmp) — the canonical callback example in C
  • Dispatch table: struct Ops { void (*open)(...); void (*read)(...); } — like a vtable
  • Function pointers enable runtime polymorphism without classes — the Linux kernel uses this pattern throughout
🕑 45 min
Lesson 5

POSIX basics: processes, signals, and sockets

fork/exec, waitpid, kill/signal, socket/bind/listen/accept basics, and why POSIX is the bedrock of Unix-like systems.

Prerequisite: Lessons 1–4

What to look for:

  • fork(): creates a copy of the process; returns 0 in child, child PID in parent
  • exec() family: replaces the current process image with a new program
  • Signals: SIGINT (Ctrl-C), SIGTERM (graceful stop), SIGKILL (immediate, can't be caught)
  • Sockets: socket() creates fd; bind() assigns address; listen() marks it as server; accept() blocks for connection
🕑 50 min

After this track: You understand C at the systems level. Good next steps: read the Linux kernel source (particularly a simple driver), work through Beej's Guide to Network Programming (beej.us/guide/bgnet/), or study K&R cover-to-cover. Consider learning C++ for RAII-based memory safety or Rust for memory safety without runtime cost.

Track quiz

4 questions to check your understanding.

What does p + 2 mean when p is an int*?

What is undefined behaviour in C?

In a linked list free function, why must you save next before calling free(current)?

In POSIX, what value does fork() return in the child process?

← Practitioner