Skip to content

Search is only available in production builds. Try building and previewing the site to test it out locally.

Test MDX File V6

This is a Test MDX File for the Pointer Lab interactive.

Check out this basic Hello World example:

Pass-by-Value, Pass-by-Reference, Pass-by-Pointer

Section titled “Pass-by-Value, Pass-by-Reference, Pass-by-Pointer”

C++ gives you three ways to hand a variable to a function. They look almost identical at the call site but produce dramatically different memory pictures and behaviours. The component below lets you flip between the three modes and scrub through the call to see exactly what each one does.

Default example — value = 10, function adds 5. Try each of the three modes and scrub through the phases.

C++ Pass-By Lab

See what changes — and what doesn't — when you pass by value, by reference, or by pointer.

How is the argument passed?

// Function definition
void modify(int x) {
    x += 5;
}

// Caller
int main() {
    int value = 10;
    modify(value);
    // value is now still 10
    return 0;
}
main()caller frame
0x7FFFE020
E024
E025
E026
E027
value @ 0x7FFFE020 · 4 bytes
modify()not yet called
0x7FFFE000
E000
E001
E002
E003
E004
E005
E006
E007

Execution phase

Before call

A copy of value is made. Inside the function, x lives in its own bytes with its own address.

What main sees after the call

int value = 10; scrub to "After return" to compare
Try this:Step through all three phases for each mode. Notice that the call site reads modify(value) for both int x and int& x — identical syntax, different meaning. Only the pointer mode forces the caller to write &value. After return, look at the value summary: by-value leaves it untouched; by-reference and by-pointer can both reach back and modify it.

A second example using assignment instead of addition, and a different starting value:

Pass-By Lab — Reset to Zero

See what changes — and what doesn't — when you pass by value, by reference, or by pointer.

A third example showing the pointer-only nullify action — note that even though the local pointer is cleared, value in main is untouched because the change to x itself doesn’t reach back across the frame boundary:

Pass-By Lab — Pointer Reassignment

See what changes — and what doesn't — when you pass by value, by reference, or by pointer.

When you declare a variable normally — int x = 42; — it lives on the stack, a fast region of memory tied to the current function call. It’s automatic: the stack grows when the function is entered, shrinks when it returns, and you never write a free-statement for it.

When you write new, you’re allocating on the heap instead. The heap persists indefinitely — until you say delete — and it lives at completely different addresses from the stack. The pointer holding the heap address still lives on the stack, which is why ending the function destroys the pointer but not what it points at.

The lab below lets you build up a small program one statement at a time and see exactly what’s happening in each region.

C++ Stack & Heap Lab

Allocate, dereference, free — and see what survives when the program ends.

Stack — main()fast · automatic · scoped
base = 0x7FFFFFE8
FFE8
FFE9
FFEA
FFEB
FFEC
FFED
FFEE
FFEF
FFF0
FFF1
FFF2
FFF3
FFF4
FFF5
FFF6
FFF7
Heapmanual · persists until delete
base ≈ 0x00557000
Heap is empty. Click int* p = new int(42); to allocate.

Click a statement to execute it

Try this:Click int* p = new int(42); then immediately End program — watch the heap block turn red. Now Reset, do the same sequence but click delete p; before ending. Compare. Then try clicking delete p; followed by *p = 99; — that's a use-after-free, one of the most common bugs in C++ (and the kind Rust's borrow checker rules out at compile time).