Instructor Guide: C++ Pointers & Dynamic Memory

A comprehensive teaching guide covering memory model fundamentals through modern smart pointers.

4
Sessions
~320
Minutes Total
45
Slides
2
Exercises

Quick Start

Opening the Slides

Open cpp-pointers-enhanced.html in any modern browser. No server or build step required.

Navigation Controls

KeyAction
/ Previous / Next slide
SpaceAdvance to next slide
TToggle Table of Contents overlay

Exercise links on slides sE1 and sE2 open in new tabs automatically.

Materials Inventory

FileDescriptionEst. Time
cpp-pointers-enhanced.html Main slide deck (45 slides) ~320 min across 4 sessions
exercise-pointer-basics.html Exercise 1: Pointer tracing, debugging, swap function (8 problems) ~25–30 min
exercise-dynamic-memory.html Exercise 2: Heap tracing, bug hunting, DynArray, smart pointers (13 problems) ~30–35 min

Session 1 (~80 min): Pointer Fundamentals

Slides: s1, s2, s2b, s3, s3b, s4, s4b, s5, s5b, s6, s6b, s7, s8, s8b, sCA, sE1

SlideTitleType~MinInstructor Notes
s1Pointers & Dynamic MemoryTitle2Welcome, set expectations. Every variable has an address.
s2What Is Memory?Interactive4Click addresses to show value lookup. Apartment analogy. Emphasize stack vs heap distinction.
s2bHow Variables Are StoredStep-through4Step through each variable (int=4B, char=1B, double=8B, bool=1B). Mention sizeof.
s3Your First PointerInteractive5Change x value with slider. Treasure map analogy: x=treasure, p=map, *p=follow map.
s3bWhy Do We Need Pointers?Lecture3Three reasons: avoid copies, dynamic data structures (linked list), polymorphism.
s4Declaring & Using PointersStep-through54-step walkthrough: declare int, declare pointer, point to val, read through pointer.
s4bPointer Syntax GotchasLecture4Three traps: int* p, q (q is not pointer!), style wars, const pointer combos. Read right-to-left rule.
s5The Dereference Operator (*)Interactive4Set *p value interactively. Remote control analogy.
s5bPointers & Function ParametersStep-through5Broken swap (by value) vs working swap (by pointer). 4-step animation.
s6Pointer Arithmetic & ArraysInteractive5p++ advances, p-- retreats. Key: moves by sizeof(type), not 1 byte.
s6bPointer Arithmetic Deep DiveInteractive4Type selector (int/char/double) changes scaling visualization.
s7nullptrLecture3nullptr vs NULL vs 0. Always check before dereferencing.
s8References vs PointersLecture4Comparison table. References can't be null, can't reassign.
s8bPass by Reference vs PointerLecture3When to use each. Reference = simpler, pointer = nullable/reassignable.
sCAChallenge A: Pointer TracingChallenge83 snippets. Students pick output. Discuss after.
sE1Exercise 1Exercise25Open exercise-pointer-basics.html. Walk around. ~25–30 min.
Buffer: If short on time, combine s6b with s6 or skip sCA discussion (let students verify on their own).

Session 2 (~80 min): Stack/Heap & Dynamic Memory

Slides: s9, s9b, s9c, s10, s10b, s11, s11b, sCB0, s12

SlideTitleType~MinInstructor Notes
s9Stack vs HeapStep-through5Animated stack frames. Key distinction: auto vs manual lifetime.
s9bStack Frames in DetailInteractive5Visualize function calls pushing/popping frames.
s9cWhen Stack Isn't EnoughLecture4Three scenarios: runtime-sized data, outlive scope, large allocations.
s10new and deleteStep-through5Show allocation/deallocation. Emphasize: every new needs a delete.
s10bnew Can FailLecture4std::bad_alloc, nothrow variant. Rare but important.
s11Dynamic ArraysStep-through5new int[n] and delete[]. Array vs single allocation.
s11b2D Dynamic ArraysInteractive5Array of pointers pattern. Nested allocation/deallocation.
sCB0Challenge: Stack or Heap?Challenge86 questions. Good formative assessment checkpoint.
s12Memory LeaksInteractive5Visualize leak. Growing memory usage graph.
Buffer: If ahead of schedule, preview s13 (Dangling Pointers) briefly.

Session 3 (~80 min): Pitfalls & Smart Pointer Intro

Slides: s13, s13b, s14, s14b, sCB, sE2, s15, s15b, s16, s16b

SlideTitleType~MinInstructor Notes
s13Dangling Pointers & Double FreeInteractive5Two most dangerous bugs after leaks.
s13bValgrind & AddressSanitizerLecture4Demo commands if time. Show sample output.
s14Rule of ThreeLecture5If you need destructor, you need copy constructor + copy assignment.
s14bShallow vs Deep CopyInteractive5Toggle visualization. Critical for understanding ownership.
sCBChallenge B: Spot the BugChallenge84 bug identification questions. Great discussion opportunity.
sE2Exercise 2Exercise30Open exercise-dynamic-memory.html. Parts A–D. ~30–35 min.
s15Smart Pointers — RAIILecture4Transition to modern C++. "Resource Acquisition Is Initialization."
s15bWhat Is RAII?Interactive5Lifecycle visualization.
s16unique_ptrStep-through5Exclusive ownership. Move semantics intro.
s16bunique_ptr PatternsLecture4Factory pattern, container usage, custom deleters.
Buffer: Exercise 2 is the anchor — prioritize giving students full time for it.

Session 4 (~80 min): Shared Pointers & Review

Slides: s17, s17b, s17c, s18, s18b, sCC, sQ1, sQ2, sQ3, sQ4

SlideTitleType~MinInstructor Notes
s17shared_ptrInteractive5Reference counting visualization.
s17bweak_ptr — Breaking CyclesLecture5Circular reference problem. Observer pattern.
s17cSmart Pointer Cheat SheetReference3Quick comparison table. Good handout material.
s18Key TakeawaysLecture4Summary of all 4 sessions.
s18bCommon Interview QuestionsLecture5Real interview prep. Engage students.
sCCChallenge C: Manual vs SmartChallenge84 scenarios picking the right smart pointer.
sQ1Quiz: Pointer ConceptsQuiz53 fundamental questions.
sQ2Quiz: Memory TraceInteractive8Step-through trace. No graded questions, just visual walkthrough.
sQ3Quiz: Pick the Right ToolQuiz54 scenario-based questions.
sQ4Bonus Quiz: Mixed BagQuiz84 harder questions. Great for review.
Buffer: sQ4 is a bonus — skip if running short. sQ2 is self-paced, good for wrap-up.

Exercise 1 Answer Key (8 points)

Part A: Pointer Tracing (4 problems)

A1 — Simple Dereference
VariableValue
a20
*p20
b25

*p = 20 changes a to 20 (p points to a). Then b = *p + 5 = 25.

A2 — Two Pointers
VariableValue
x20
y50
*p50
*q50
p==qtrue

*p = *q copies y's value (20) into x. p = q makes p point to y. *p = 50 changes y to 50. Both p and q now point to y.

A3 — Pointer Arithmetic
VariableValue
*p20
val60

p starts at arr[0], p++ moves to arr[1] (20). *(p+2) = arr[3] = 40. val = 20 + 40 = 60.

A4 — Pointer Reassignment
VariableValue
a11
b4
c15

p→a: *p = 1+10 = 11. p→b: *p = 2*2 = 4. p→c: *p = 11+4 = 15.

Part B: Fix the Code (3 problems)

B1 — Uninitialized Pointer

Bug: p doesn't point to valid memory.

Fix:

int x;
int* p = &x;
*p = 42;

Or: int* p = new int; *p = 42;

B2 — Wrong Operator

Bug: &p gives address of the pointer itself, not the value it points to.

Fix: int y = *p;

B3 — Memory Leak

Bug: First allocation (42) is never freed before reassignment.

Fix:

int* p = new int(42);
delete p;
p = new int(99);
delete p;

Part C: Swap Function (1 problem)

C1 — Pointer-based Swap
void swap(int* a, int* b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

Exercise 2 Answer Key (13 points)

Part A: Heap Tracing (4 problems)

A1 — Alias & delete
LineHeapStack
1int(10)p→heap
2int(10)p→heap, q→heap (same address)
3int(20)p→heap, q→heap
4freedp, q dangling

After delete, both p and q become dangling pointers.

A2 — Copy value & nullptr
LineHeapStack
1int(5)a→heap
2int(5), int(10)a→5, b→10
3int(13), int(10)a→13, b→10
4int(13)a→13, b dangling
5int(13)a→13, b=nullptr

*a = *b + 3 copies the VALUE (13), not the pointer. After delete b and b = nullptr, a still points to 13.

A3 — Array & pointer arithmetic
LineHeapStack
1[?,?,?]arr→heap
2[10,20,30]arr→heap
3[10,20,30]arr→heap, p→arr[1]
5freedarr, p dangling

p = arr + 1 points to the second element (20). After delete[], the entire array is freed.

A4 — Pointer to pointer
LineHeapStack
1int*(→int(42))pp→heap
3int*(dangling)pp→heap
4emptypp dangling

Two heap blocks: int* (pointing to int(42)). delete *pp frees the int, delete pp frees the int*. Both gone.

Part B: Memory Bug Hunt (4 problems)

B1 — Early return leak

Bug type: Memory Leak

The early return skips delete[] data, leaking memory.

Fix: Add delete[] data; before the return, or restructure the logic.

B2 — Returning address of local

Bug type: Dangling Pointer

val is destroyed when function returns; pointer becomes dangling.

Fix: Allocate on heap with new int(42) and return that.

B3 — Double free

Bug type: Double Free

a and b point to the same address; deleting both is a double free.

Fix: Only delete once, set the other to nullptr.

B4 — Wrong delete form

Bug type: Mismatched new/delete

new int[100] must be paired with delete[] arr, not delete arr.

Fix: delete[] arr;

Part C: Build a Dynamic Array (3 problems)

C1 — Constructor
DynArray(int cap) {
    data = new int[cap];
    size = 0;
    capacity = cap;
}
C2 — Destructor
~DynArray() {
    delete[] data;
}
C3 — push_back
void push_back(int val) {
    if (size == capacity) {
        capacity *= 2;
        int* newData = new int[capacity];
        for (int i = 0; i < size; i++)
            newData[i] = data[i];
        delete[] data;
        data = newData;
    }
    data[size++] = val;
}

Part D: Smart Pointers (2 problems)

D1 — unique_ptr
void process() {
    auto p = make_unique<int>(42);
    cout << *p;
    // no delete needed -- RAII handles cleanup
}
D2 — shared_ptr
auto w = make_shared<Widget>();
componentA->use(w);
componentB->use(w);
// no delete needed -- last owner frees automatically

Quiz & Challenge Answer Key

Challenge A — Pointer Tracing (sCA)

Challenge A Answers (3 snippets)
QAnswerExplanation
Snippet 1c) 20 30a starts 5, *p=20 changes a to 20, then p moves to b, *p=30 changes b to 30.
Snippet 2d) 42 42p1 and p2 both point to x. *p2=42 changes x. So x=42 and *p1=42.
Snippet 3b) 2 2 0*p = *q copies the VALUE (2→a), but p still points to a and q to b. p != q.

Challenge: Stack or Heap? (sCB0)

Stack or Heap Answers (6 questions)
QCodeAnswerExplanation
1int x = 42;StackLocal variable → stack.
2int* p = new int(10); — where is p?StackThe pointer p itself is on the stack.
2bint* p = new int(10); — where is *p?HeapThe int(10) is allocated with new → heap.
3string s = "hello";Stack (string object)The string object lives on the stack (internal buffer may be on heap — hidden).
4int arr[5];StackFixed-size local array → stack.
5int* arr = new int[5];Heapnew int[5] → array data is on the heap.
6static int count = 0;Neither (data segment)Static variables are in the data segment — neither stack nor heap!

Challenge B — Spot the Bug (sCB)

Spot the Bug Answers (4 questions)
QAnswerExplanation
Bug 1a) Memory LeakThe early return skips delete[] arr — memory leak!
Bug 2c) Double Freep and q point to same memory. Deleting both = double free!
Bug 3d) Wrong Deletenew[] must match delete[]. Using plain delete on array = wrong delete!
Bug 4b) Dangling Pointerval is a local variable. Returning its address = dangling pointer!

Challenge C — Manual vs Smart (sCC)

Manual vs Smart Answers (4 scenarios)
QScenarioAnswerExplanation
1Single-owner file handlea) unique_ptrSingle owner → unique_ptr. Auto-deletes when scope ends.
2Cache shared by multiple componentsb) shared_ptrMultiple owners, shared lifetime → shared_ptr with reference counting.
3Pass existing object to functionc) Reference (&)Not owning, just observing → pass by reference. No allocation needed.
4Factory returns to callera) unique_ptrFactory returns ownership → unique_ptr. Caller gets exclusive ownership.

Quiz: Pointer Concepts (sQ1)

Pointer Concepts Answers (3 questions)
QQuestionAnswerExplanation
1What does &x give you?b) The memory address of x& is the "address-of" operator.
2What is *p when p is a pointer?b) The value at the address p stores* is the dereference operator.
3What is nullptr?b) A special value meaning "points nowhere"Type-safe (unlike C's NULL).

Quiz: Pick the Right Tool (sQ3)

Pick the Right Tool Answers (4 questions)
QScenarioAnswerExplanation
1Modify caller's variabled) Reference (&)Just modifying — use a reference. Simplest, no ownership.
2Linked list node→nextb) unique_ptrEach node exclusively owns next → unique_ptr for clear ownership.
3Texture shared by game objectsc) shared_ptrMultiple objects share one texture → shared_ptr with ref counting.
4Factory creates and returnsb) unique_ptrFactory creates and transfers ownership → unique_ptr.

Bonus Quiz: Mixed Bag (sQ4)

Mixed Bag Answers (4 questions)
QQuestionAnswerExplanation
1What prints? (reference + pointer)b) 10 10r is alias for x, &r == &x. *p=10 changes x. Both x and r are 10.
2How many bytes leaked?c) 40 bytesa=b loses pointer to first array (10 ints x 4B = 40B leaked). Second array properly deleted.
3Is auto p=make_unique, auto q=move(p), cout<<*p safe?b) No, p is nullptr after moveAfter move, p is nullptr. Dereferencing = UB/crash.
4What's wrong with foo(x) where foo takes unique_ptr by value?b) Compile error: can't copy unique_ptrunique_ptr can't be copied. Need foo(std::move(x)).