student@ubuntu:~$
c 4/5 35 XP

Valgrind

0%

Quick Reference

Basic workflow:

gcc -g -Wall -o program program.c    # Compile with debug info
valgrind --leak-check=full ./program  # Run under Valgrind

What to look for:

Valgrind says Meaning Fix
All heap blocks were freed No leaks You’re done
definitely lost: N bytes Memory leak Add missing free()
Invalid read of size N Reading memory you don’t own Check array bounds, check for use-after-free
Invalid write of size N Writing memory you don’t own Check buffer sizes, check for use-after-free
Invalid free() Double free or freeing non-heap memory Remove duplicate free()
uninitialised value Using uninitialized memory Use calloc or initialize before reading
N allocs, M frees Should be equal Find the N-M missing free() calls

Reading the output:

==12345== Invalid read of size 4          ← What: reading 4 bytes illegally
==12345==    at 0x40069C: main (prog.c:7) ← Where: line 7 of prog.c
==12345==  Address is 0 bytes after a     ← Why: right past end of
==12345==  block of size 20 alloc'd       ←       a 20-byte allocation
==12345==    at 0x4C2ABCD: calloc         ← Origin: allocated via calloc
==12345==    by 0x401200: main (prog.c:4) ←         at line 4

Common Pitfalls

  • Forgetting -g — Without debug symbols, Valgrind shows hex addresses instead of file:line.
  • Testing only the happy path — Valgrind only catches bugs that execute. Test edge cases.
  • Ignoring “still reachable” — Usually not a bug, but clean it up for good hygiene.
  • Nested allocations — A struct with char *name needs TWO frees. Valgrind counts each.
  • Reading Valgrind output bottom-up — The allocation origin is at the bottom. The error location is at the top.

Unlocks

Complete this skill to see what it unlocks.