Memory and Program Execution

Every variable this series' programming-fundamentals topic described as a "named box" is, underneath the name, just a numeric address into the DRAM this site already covers at the device level — the name is purely a convenience the compiler erases, and what actually exists at runtime is a flat sequence of addressable byte locations. An address is simply that location's number, exactly like a street address, and a pointer (sometimes called a reference, depending on the language) is a variable whose value is itself an address — instead of holding `42`, a pointer holds "the number 42 lives over there, at address 0x7ffee2a1," which lets a program pass around a location rather than copying the data at that location every time, a real and significant efficiency difference once the data is large. A running program's memory splits into two very differently managed regions. The stack holds local variables and function call information, and it is strict and fast specifically because it's simple: each function call pushes a new frame onto the top, that frame's variables live exactly as long as the function is running, and the frame pops off automatically the instant the function returns — no bookkeeping required, which is also exactly why a stack variable's lifetime is so predictable and why deeply nested or infinite recursion causes a stack overflow once too many frames pile up with nowhere left to grow. The heap is the opposite tradeoff: slower and more flexible, used for data whose size or lifetime isn't known until the program is actually running, requested explicitly by the program (`ALLOCATE 1000 bytes`) and not automatically freed when a function returns — which is exactly the danger. A memory leak happens when a program allocates heap memory, loses every pointer that could reach it again, and never frees it, so that memory sits permanently unusable until the program exits; a dangling pointer is the opposite and arguably worse mistake, where a program frees memory and then a leftover pointer still tries to read or write through that now-invalid address, corrupting whatever unrelated data has since moved into that freed space. Object lifetime is the general name for this whole question — exactly when a piece of data comes into existence and exactly when it stops being valid to use — and it is answered completely differently by stack variables (automatic, tied to the function call) versus heap variables (manual, tied to an explicit allocate and an explicit free that the programmer is fully responsible for getting right in languages without automatic garbage collection). A simple memory allocator, a genuinely instructive systems-programming project, has to solve exactly this problem for every other program running on top of it: track which chunks of a large raw memory block are currently in use, hand out a free chunk of the right size on request, and merge adjacent freed chunks back together so the available space doesn't fragment into pieces too small to be useful — the exact bookkeeping problem this topic describes, just made into the actual deliverable instead of something hidden behind a language's `ALLOCATE` keyword.

Program requests memory for new data
size unknown until runtime
Allocator finds a free chunk of the right size
heap bookkeeping, tracked internally
Pointer returned to the program
holds the address, not a copy of the data
Correct path: program frees it when done
chunk returned to the free list
Leak: no pointer ever frees it
chunk stays reserved forever
Dangling pointer: freed, then used anyway
reads or writes now-invalid memory
Stack vs. Heap: Two Regions, Two Lifetimes Both are just addressed locations in the same physical DRAM Stack main() frame calculate() frame validate() frame — top of stack pops off automatically when the function returns grows and shrinks with each call Heap in use free in use lives until explicitly freed — forgetting is a leak size and timing decided at runtime a stack overflow is simply running out of room to push another frame
Two Ways to Misuse Heap Memory Both come from losing track of an address Memory leak allocated chunk, address 0x5A2 every pointer to it is gone chunk stays reserved forever wastes memory, doesn't corrupt it Dangling pointer freed — address 0x5A2 reusable old pointer still reads/writes it corrupts whatever moved in actively corrupts unrelated data a simple memory allocator exists to prevent exactly these two failure modes

Everything in the rest of this curriculum that touches performance or correctness traces back to this topic: data structures next in the series are literally defined by how they lay out and link memory addresses, concurrency later introduces the added danger of two threads racing to read and write the same address at once, and computer architecture will show the actual hardware — registers, cache, DRAM rows and columns — that makes some of these addresses dramatically faster to reach than others.

Take memory and program execution further

Ask the copilot about this term, or have our engineers assess it against your process.