Crux Read memory diagrams and small snippets, do address arithmetic, trace a pointer dereference, and decide stack vs heap placement.
Your altitude — climbing toward senior
ZeroJuniorMiddleSenior
You are at middle altitude — in the sky
◷ 14 min
Memory questions are really diagram questions. Read each layout or snippet, trace what the machine does cell by cell, and pick the answer that matches the model — address vs value, byte offsets, dereferencing, and where data lives.
Goal
Practise the moves you will repeat forever: read a memory diagram, compute a byte address by offset, follow a pointer one hop, and reason about whether a value sits on the stack or the heap.
Snippet 1 — a memory diagram
addr: 0 1 2 3 4 5value: 25 30 3 0 99 12
Quiz
Completed
The cell at address 2 holds the value 3, and the program treats address 2 as a pointer. Dereference it: what value comes back?
Heads-up The value 3 in the pointer cell is an address, not the final data. Dereferencing reads address 3 next, which holds 0. The answer is 0.
Heads-up Dereferencing starts at the pointer cell (address 2), not at address 0. Read address 2 to get 3, then read address 3 to get 0.
Heads-up Dereferencing follows the stored address, it does not scan for a maximum. Address 2 holds 3, and address 3 holds 0, so the result is 0.
Snippet 2 — address arithmetic
A 32-bit integer array starts at address 200.Each element is 4 bytes (32 bits) wide.Elements are laid out back-to-back with no gaps.
Quiz
Completed
At what byte address does element index 3 (the fourth element) begin?
Heads-up Each element is 4 bytes wide, so you advance by index * 4, not by index * 1. The offset is 3 * 4 = 12, giving 200 + 12 = 212.
Heads-up Index 3 is the fourth element (indices start at 0), and its offset is 3 * 4 = 12. That gives 212, not 216. Using 4 * 4 would be index 4.
Heads-up Only index 0 sits at the base. Index 3 is three elements further along: 200 + 3 * 4 = 212.
Snippet 3 — stack vs heap placement
int* make_counter() { int local = 0; // line A int* shared = malloc(sizeof(int)); // line B *shared = 0; return shared; // returns a heap pointer}
Quiz
Completed
After make_counter returns, which of local (line A) and the malloc'd int (line B) still safely exists, and why?
Heads-up Being an integer is irrelevant to lifetime; placement is. local sits in the stack frame and dies with it. Only the heap allocation from malloc outlives the call.
Heads-up Declaration order does not set lifetime. local is in the stack frame and is gone after the return; the heap allocation (line B) is what persists.
Heads-up Returning frees the stack frame, but heap memory from malloc is independent of the call and persists until explicitly freed. The line B allocation survives.
Snippet 4 — a write trace
Start: addr 10 -> 7, addr 11 -> 0Op 1: write value 4 to address 11Op 2: write value 9 to address 10Op 3: write value 0 to address 10
Quiz
Completed
After all three writes, what values are at addresses 10 and 11?
Heads-up A write overwrites; it does not add or stack values. Op 3 replaces the 9 with 0, so address 10 ends at 0, not 9.
Heads-up A write affects only its target address. Op 3 sets address 10 to 0 but leaves address 11 at 4, the value Op 1 wrote.
Heads-up Writes are destructive and permanent until the next write to that cell. The originals are gone: address 10 ends at 0 and address 11 at 4.
Recap
Every problem here is solved by reading the diagram literally: a value can be an address, so dereferencing means a second read at that address; an array element’s byte address is base + index * elementSize; a value’s survival after a function returns depends on whether it sat on the stack frame (gone) or the heap (persists); and a write overwrites exactly one cell, last-write-wins, touching no other address. Trace cell by cell and the answer is forced.