By the end of this lesson, cadets will be able to:
valgrind to detect memory errors. (Outcome 3, 7)Complete before class. The Beej sections set up the realloc material; the supplementary notes introduce valgrind, which is new to CS210.
| Source | Sections | Why |
|---|---|---|
| Beej-C | Chapter 12, §12.5 (realloc) and §12.6 (typical bugs) | Continues from L15. realloc is the one heap call not yet covered; §12.6 lists the bug classes we will hunt today. |
| Supplementary notes | valgrind primer (linked in Section 4) | valgrind is new to CS210. The primer covers what it does, how to run it, and how to read the report it produces. |
realloc and the loses-original patternYesterday you learned the rules of the heap. Today is the day those rules get broken, and the day you learn to find the breaks. valgrind is a runtime tool that watches every allocation and every memory access your program makes. When something goes wrong, it tells you what kind of wrong, where it happened in your source, and (often) which earlier allocation is involved. Reading its output is a skill on its own.
The Lesson 16 deck covers the six bug classes, one slide per class, with the valgrind output for each. Then a workflow slide on reading the output, then an honest look at what valgrind cannot catch.
Open Lesson 16 slides → replace href with your SharePoint link
These are the six classes valgrind catches reliably. They cover almost every heap-related crash you will write in this course. Memorize the names; the bug log in the lab asks for them.
| Bug class | What it means | valgrind signal |
|---|---|---|
| Memory leak | Allocated with malloc, never freed. No live pointer at program exit. | definitely lost |
| Use-after-free | Read or write through a pointer after that block was freed. | Invalid read/write of size N |
| Out-of-bounds write | Wrote past the end (or before the start) of an allocation. | N bytes after a block |
| Uninitialized read | Used a heap value before storing anything into it. Garbage in, garbage out. | uninitialised value |
| realloc loses original | Assigned realloc's result directly to the only pointer to the old block. On failure, the old block leaks AND the pointer is NULL. | leak; pattern visible in source |
| Double-free | Called free on the same block twice. Corrupts the heap. | Invalid free / double free |
realloc(ptr, new_size) resizes an existing heap block. It may grow the block in place or copy the contents to a new larger block and free the old one. Either way, you must use its return value.
The trap is the natural-feeling pattern:
If realloc fails, it returns NULL. The old block is still valid and still allocated; you just lost the only pointer to it. Now you cannot read from it and you cannot free it.
This is one of the bugs in today's lab.
valgrind is not a debugger. You do not step through code with it. You run your program under it, and it watches every memory access. When it sees something suspicious, it prints a report.
Two things matter. First, compile with -g so valgrind can show you file names and line numbers. Second, read the output from the top. Errors cascade. The first one is almost always the most useful; the rest are often consequences of the first.
The loop:
valgrind is a runtime tool, so it only sees the code paths your test inputs actually exercise. A bug that lives in an error-handling branch never visited by your tests stays hidden. Reading the code matters too.
valgrind also does not catch:
A clean valgrind report does not mean your program is bug-free. It means your program is not making the specific class of mistakes valgrind watches for, on the specific inputs you ran.
Two things to do in class. The widget builds your pattern recognition; the lab applies it under valgrind.
Twelve tasks across four mini-programs. Read the source, read the valgrind output, and classify what is wrong. The point is to build the pattern: what does each bug class look like in the report?
Enter your name. It will appear on the completion screen so you can include it in your screenshot for the Lesson 16 reflection.
valgrind --leak-check=full ./prog. Each task asks one specific thing: classify the bug (one or two words), point to the line in the source, or describe the fix. Mistype twice and the hint button will pulse.
valgrind_before.txt and point at the specific error you do not understand. Pointing at a specific message gets you unstuck in five minutes; "my code does not work" takes thirty. Check the course Resources section first for valgrind primers and Git troubleshooting before scheduling.