CS310 — Understanding Memory Addresses in C++
A pointer is a variable that holds a memory address. This deck covers declaration, dereferencing, pointer arithmetic, arrays, and function parameters.
Every variable lives at a specific memory address
5 or 'A', it stores the address of another variable.
Syntax, spacing, and the declaration trap
The * binds to the variable name, not the type. Each pointer variable needs its own *.
Always check for NULL before dereferencing: if (ptr != nullptr)
nullptr.
& and *Address-of and dereference — the yin and yang of pointers
& gets the address of a variable. * follows an address to get the value. They undo each other: *(&x) == x.
Step through a complete program and watch memory change
Type matching and the null pointer
int* reads 4 bytes, a double* reads 8 bytes. Mixing them would read the wrong amount of memory.
An uninitialized pointer contains whatever was previously in that memory — it could point anywhere, causing hard-to-debug crashes.
nullptr is like writing "NO ADDRESS" — at least you know not to follow it.
pX = pY vs *pX = *pYTwo very different operations that look similar
pX = pY — copies the address (now both point to y)*pX = *pY — copies the value (x gets y's value, pointers unchanged)An array name IS a pointer to the first element
vals[i] is syntactic sugar for *(vals + i). The compiler translates array indexing into pointer arithmetic.
*vals + 1 ≠ *(vals + 1). The first dereferences then adds 1 to the value. The second adds 1 to the pointer then dereferences.
Increment, decrement, add, subtract — all scaled by type size
ptr + 1 advances by sizeof(int) = 4 bytes, not 1 byte. The compiler handles the scaling.
Array notation and pointer notation are interchangeable
list[i] — array subscript*(list + i) — pointer arithmeticptr[i] — pointer with subscript*(ptr + i) — pointer math on variablelist[100] — it will happily read garbage memory. This is a common source of bugs and security vulnerabilities.
Address comparison vs content comparison
p1 == p2 — "Do they point to the same memory location?"*p1 == *p2 — "Do the values they point to happen to be equal?"Trace the pointer operations and predict the values
Passing addresses to functions to modify the caller's variables
* in the function parameter: int *p* in the function body to dereference: *p = ...& in the call to pass the address: doubleIt(b, &a)Three approaches — only two actually work
Swaps local copies only. Originals untouched.
x and y are aliases for a and b.
Dereference to access originals.
& at call site, no * to dereference). Pointers are more flexible (can be reassigned, can be NULL, needed for dynamic memory).
x = y; y = x;) instead of the values they point to (*x = *y; *y = *x;). The first just changes local pointer copies!
This swap function doesn't work. Why?
Array parameters are always pointers under the hood
size separately.
const when the function shouldn't modify the array. This catches accidental writes at compile time.
Watch the pointer-based swap execute step by step
Quick reference for all pointer operations
Avoid these — they cause crashes, corruption, and security vulnerabilities
The mental model to carry forward
int *p;p = &x;*p&xp++*(p+i)arr[i]≡*(arr+i)void f(int *p)nullptrconst int *p& gets addresses, * follows them. Everything else — arrays, arithmetic, parameters — builds on this.
Pick the right approach for each scenario
arr&x return?int *p, q; declares:ptr+1 for an int* advances by:What are the final values?
What does this program print?