Pointers are the part of C and C++ where most learners give up, most bugs live, and most seniors eventually prove their worth. This series takes them apart slowly. Each post is built around a single idea, derived from the problem it solves, and paired with interactive visualisations you can play with. By the end, every major pointer concept, from addresses to unique_ptr to undefined behaviour, feels like something you built yourself.
Each part builds on the last. Read in order. Sidebar on each page tracks where you are. Every post ends with a quiz you can use to check yourself before moving on.
& asks "where?" and * asks "what's there?". A mental picture of memory as numbered boxes, and what it means for one box to hold the number of another.sizeof trap, and why a function parameter that "takes an array" is really taking a pointer.const int*, int* const, and const int* const look similar and mean very different things. The right-to-left reading rule, top-level vs low-level const, and why const-correctness spreads.memcpy, and restrict as a trust contract. Why const and restrict solve different problems, and what the compiler is allowed to assume about each.malloc, qsort, callback user data, and opaque library handles all rest on the same mechanism. And the hazards that come with switching off type-checking.unique_ptr, shared_ptr, weak_ptr. When to reach for each, and why one of them is the default.Starting from "a pointer is a variable that holds an address," eleven posts later you've covered everything a working C or C++ programmer actually uses: the mechanics, the bugs, the contracts, the modern-C++ tools for ownership, and the discipline for staying out of undefined behaviour. You've seen the ideas motivated, not announced. You've watched the pieces assemble.
The tools and habits from these posts are what the rest of a C or C++ career is built on. Every complicated system, every clever data structure, every optimised inner loop, is some combination of addresses, lifetime, ownership, aliasing, and the type-system contracts that hold it all together. Get those right and the rest follows.
The next step isn't more reading. It's writing. Build something with dynamic memory. Ship it. Run it under AddressSanitizer. Read a serious C or C++ codebase and argue with its ownership decisions. The knowledge in this series turns into fluency the moment you start stress-testing it against real code.