Memory & Pointers

a stack frame

When a function is called, it needs its own little desk to work at — somewhere to keep its arguments, its local variables, and a note of where to return. A stack frame, also called an activation record, is exactly that desk: the slice of the call stack belonging to one active call. Each call gets a fresh frame; when the call ends, the frame is cleared away.

A frame typically holds the function's local (automatic) variables, copies of its arguments, the return address back into the caller, and often a saved copy of the caller's frame-pointer register (rbp on x86-64) so the layout can be unwound cleanly. The frame is set up by a short prologue at the function's start (which adjusts the stack pointer to carve out space) and torn down by an epilogue at the end (which releases that space and jumps to the return address). Local variables are simply named offsets inside this frame — for instance the compiler might place int x at rbp - 4 — which is why locals come into being on entry and cease to exist on return.

The frame is why local variables are 'automatic': they are created automatically when the frame is pushed and destroyed automatically when it is popped, costing essentially nothing. It is also the source of a classic bug — returning the address of a local variable hands back a pointer into a frame that no longer exists, a dangling pointer into reclaimed stack memory. The frame did its job and went away; the address that survived now names garbage.

int *bad(void) { int local = 5; return &local; } — bad returns the address of local, but local lived in bad's frame, which is gone the moment bad returns. The caller holds a dangling pointer; using it is undefined behaviour.

Returning &local is a classic bug — the frame is gone, the address is stale.

A frame's locals exist only for the duration of that one call; nesting the same function (recursion) gives each call its own separate frame and its own copy of the locals. Never return or stash a pointer to a local — once the function returns, its frame is reused and the pointer dangles.

Also called
activation recordcall frame活動記錄