Learning objectives
After this chapter you should be able to:
Do unaided:
- Draw the same object reached through a pointer and through a reference, and explain the three rules that make a reference different from a pointer.
- Explain what
std::string,std::vector, namespaces, overloading andconst¶meters add over their C counterparts, and predict where each keeps its data. - Identify C habits in C++ code with the seven-item checklist, and rewrite each one in modern C++.
- Write the minimum-seam recurrence, trace it on a small grid, and derive why the naive recursion is exponential while the memoized one is proportional to width × height.
May delegate:
- A C-to-C++ port of a station tool from your written spec, followed by your own habit audit.
- The memoized seam function for PA4, from your recurrence, tests and complexity budget.
Opening case
A composite case, not a real student or course.
PA4 starts with a port. Before Priyanka can add the sky-camera code, the station's C summary tool, summary.c, has to become C++. She has an agent that can edit files and run commands in her container, and she types one line: "Port summary.c to modern C++."
The chapter continues from here.
The loop in this chapter
Open a step to see what it asks of you and how it plays out in the Pair phase.
PredictBefore seeing the port, list which habits survive, whether output matches and whether the sanitizer reports; predict naive and memoized call counts.
Step 1 of 6 · You, no AI
What you hand in: A written prediction: the output, the memory state, the operation count, and how sure you are.
Why this step: A prediction written before the run is the only way to learn whether your model of the machine is right. A miss is the most useful result there is, because it shows exactly where the model is wrong.
The first prediction is never delegated.
Ask yourself: What will this print, what will memory look like when it ends, and how many operations will it take?
Log the prediction in your work log · Predict in every chapter · ← Predict in Chapter 11 · Predict in Chapter 13 →
WriteBy hand: a
stn::meantakingconst std::vector<stn::Reading>&, andseam_fromfrom the recurrence.Step 2 of 6 · You, no AI
What you hand in: One small piece written by hand, to build the mental model.
Why this step: You can only check what you could have built. Writing a small piece yourself gives you the model you will need to judge the agent's version later.
Ask yourself: Could I write this piece again tomorrow without notes?
Browse the companion code · Write in every chapter · ← Write in Chapter 11 · Write in Chapter 13 →
SpecifyThe port spec (rules, golden output, your ownership section) and the PA4 spec (signatures, recurrence, tests, O(w × h) budget, preconditions).
Step 3 of 6 · You
What you hand in: The header or class interface, unit tests, a complexity budget and the ownership rules.
Why this step: The specification is the contract the code will be held to. Tests written first, a cost budget and ownership rules turn "looks right" into something you can check.
The ownership and lifetime section of a specification is never delegated.
Ask yourself: Who allocates, who frees, what does it cost, and what input would break it?
Prompt and specification templates · Specify in every chapter · ← Specify in Chapter 11 · Specify in Chapter 13 →
DelegateThe Pair ports and writes
min_seam_memo; save prompts and transcripts.Step 4 of 6 · The agent
What you hand in: The implementation from your specification, or an explanation in the Tutor phase, with the prompts and transcript saved.
Why this step: The agent does the typing; you keep the judgment. Saving the prompts and the transcript makes the delegation something you can audit afterward.
Pair Pair phase: the agent writes small units from your specification, and you audit every line.
Ask yourself: Did I hand over my specification and tests, and did I save what the agent said?
Prompt templates · Delegate in every chapter · ← Delegate in Chapter 11 · Delegate in Chapter 13 →
AuditBuild with the book's line,
diff, scan, read against Table 12.1, test, then count and time at increasing h against your derivation.Step 5 of 6 · You and the tools
What you hand in: The Audit Report: tests, sanitizer and Valgrind output, your own cost derivation against a timing plot, the defects found, and a keep-or-rewrite decision.
Why this step: What the agent says is testimony until an instrument confirms it. Tests, sanitizers, Valgrind and a timing plot are evidence.
The final judgment that the code is correct is never delegated.
Ask yourself: What did the sanitizer report, does the timing plot match my derivation, and would I keep this code or rewrite it?
The Audit Report template · Audit in every chapter · ← Audit in Chapter 11 · Audit in Chapter 13 →
DefendWhy the port is no longer C, where each container's memory is freed, and why the seam bound is w × h, not 3ʰ.
Step 6 of 6 · You, live
What you hand in: A five-minute oral defense.
Why this step: If you can explain it live, you own it. The oral checks that the understanding is yours and not the agent's.
Ask yourself: Why this bound, what input breaks it, and where is this memory freed?
How the loop works · Defend in every chapter · ← Defend in Chapter 11 · Defend in Chapter 13 →
What agents get wrong here
Patterns observed in agent-written code, to test for, not guarantees. If the agent no longer makes the mistake, your job is to prove it got it right, with the same instrument.
Mixed C and C++ idioms: printf on a std::string, strcpy from c_str()
How to catch it -Werror=format; the habit scanner; read each conversion point
Section 12.3.1 · Compiler warnings
malloc for a type with C++ members
How to catch it Check each malloc hit's members; ASan SEGV; Valgrind uninitialized values and lost bytes; -Wclass-memaccess
Section 12.3.2 · Compiler warnings, AddressSanitizer, Valgrind
Exponential recursion where dynamic programming belongs; a memo table passed by value
How to catch it Count calls and time at increasing sizes against your derivation
Section 12.3.3 · Timing and log-log plots
What the chapter covers
- 12.1 The concept, by hand
- 12.1.1 Same machine, stricter compiler
- 12.1.2 References: another name for an object
- 12.1.3
constcorrectness - 12.1.4
std::string: text that knows its length - 12.1.5
std::vector: an array that owns its memory - 12.1.6
newanddelete, once - 12.1.7 Namespaces
- 12.1.8 Function overloading
- 12.1.9 Structs and free functions now, classes next
- 12.1.10 Spotting C habits in C++
- 12.1.11 PA4 begins:
stn::Imageand the minimum seam
- 12.2 Predict and check
- 12.3 What agents get wrong here
- 12.3.1 Mixed C and C++ idioms
- 12.3.2
mallocwith C++ objects - 12.3.3 Exponential recursion where dynamic programming belongs
- 12.4 Working with the agent
- 12.5 Lab: Port it, then list what survived
- 12.6 Defend it
Cost thread
PA4's hidden tests measure this cost. Table 12.2 comes from the full seam.cpp, built with g++ -std=c++20 -O2 (no sanitizers) on a shared 2.1 GHz virtual machine, width 10, median of five runs. The machine was busy, so runs varied by up to about 50% at larger sizes; call counts are exact.
Summary
- C++ keeps C's memory model; it adds ways for types to carry rules (length, ownership, read-only access) that C leaves in comments.
- A reference is a second name for an existing object: bound at creation, never reseated, never null. A
const T¶meter gives read-only access without a copy. std::stringandstd::vectorare small stack objects that own a heap block, know their size and free themselves; they replacechar*buffers, raw arrays,mallocand manual lengths.newanddeletemust be paired by form and should be rare in new code; a vector, string or smart pointer says in its type what a raw pointer cannot.- A port that compiles, passes the sanitizer and looks like C++ can still be C; the checklist,
-Wold-style-cast, a golden-outputdiffand a careful reading tell you. - The minimum seam has overlapping subproblems: naive recursion makes about 3ʰ calls per start pixel, memoization w + (h − 1)(3w − 2) in all, and measurement at increasing h shows the difference.
Key terms
- reference: a second name for an existing object; bound at creation, never reseated, never null.
- const-correct: marking every value, parameter and reference that should not change as
const, so the compiler enforces it. constexpr: declares a typed constant whose value is known at compile time; replaces#defineconstants.std::string: the standard text type, which owns its characters and knows its length.std::vector: the standard growable array, which owns its elements, tracks size and capacity, and frees its memory.- range-for loop:
for (T x : container), visiting each element in order without an index. new/delete: operators that allocate and construct a heap object, then destroy and release it;new[]pairs withdelete[].- namespace: a named scope, such as
stnorstd, for functions, types and constants, used with::. - function overloading: several functions with one name and different parameter lists, chosen by the compiler at each call.
- name mangling: the compiler's encoding of a function's namespace and parameter types into a unique linker symbol.
- C habit: a C idiom left in C++ where the language offers a replacement that carries the rule in the type.
- seam: a top-to-bottom path of one pixel per row, each pixel in the same column as the one above or next to it.
- overlapping subproblems: a recursion that solves the same smaller problem many times.
- dynamic programming: solving each distinct subproblem once and storing its answer.
- memoization: top-down dynamic programming: a recursion that checks a table before computing and stores what it computes.
Companion code
14 files for this chapter, compiled with the book's flags.
Read the code Download ch12.zip
Connections
Where this chapter and another point to each other most often.
- Chapter 4: Pointers
This is the third meaning of&: in&tit takes an address (Chapter 4), ina & bit is bitwise AND (Chapter 9), and after a type in a declaration it makes a reference. - Chapter 5: Arrays, Strings, and Matrices: n, n², n³
And the C original fillednamewithsnprintf; the port usesstrcpy, the unbounded copy Chapter 5 warned about. - Chapter 6: The Stack and the Heap: Dynamic Memory and Ownership
The machine has not moved: Chapter 6's stack and heap, Chapter 7's struct layout and Chapter 5's row-major arrays all hold. - Chapter 7: Structs, Headers, and Multi-File Programs
The machine has not moved: Chapter 6's stack and heap, Chapter 7's struct layout and Chapter 5's row-major arrays all hold. - Chapter 8: Growable Arrays and Linked Lists: The Cost of Growth
Figure 12.2 shows the long case. ### 12.1.5std::vector: an array that owns its memorystd::vector<T>is Chapter 8'srvec, generalized and supplied by the library. - Chapter 9: Files, Bits, and Function Pointers: ADTs Behind a Header
This is the third meaning of&: in&tit takes an address (Chapter 4), ina & bit is bitwise AND (Chapter 9), and after a type in a declaration it makes a reference. - Chapter 13: Classes, Invariants, and Operator Overloading
Classes matter (Chapter 13), but most of what changes a first C++ program is in this chapter: references, library types that own their memory, namespaces, overloading andconst. - Chapter 14: Resource Ownership: RAII, the Rules of Zero, Three, and Five, and Smart Pointers
Returninglabelby value is cheap and safe; Chapter 14 explains why. - Chapter 16: Templates and the Standard Library
The<double>says what it holds; Chapter 16 explains how (templates).
Further reading
- Stroustrup (2024), Programming: Principles and Practice Using C++, 3rd edition: the language's designer teaching modern C++ to beginners, with
std::vectorandstd::stringfrom the start. - Stroustrup and Sutter (2024), C++ Core Guidelines: the source of the rules cited here (F.16, F.60, Con.5, R.10, R.11, ES.31, ES.48, ES.49); read the rationale under any rule you break.
- Avidan and Shamir (2007), "Seam carving for content-aware image resizing": the original paper; its figures make energy and seams clear in a page.
- Cormen et al. (2022), Introduction to Algorithms, 4th edition, the dynamic programming chapter: recognizing overlapping subproblems and filling the table bottom-up as well as top-down.