# Valgrind Output **Valgrind error reports** include the error type, location (file and line), and stack trace. Learning to read them accurately is essential for debugging. A typical error report looks like: ``` ==12345== Invalid read of size 4 ==12345== at 0x109179: process (program.c:22) ==12345== by 0x1091AB: main (program.c:31) ==12345== Address 0x4a4b080 is 0 bytes after a block of size 40 alloc'd ==12345== at 0x483DD99: malloc (vg_replace_malloc.c:307) ==12345== by 0x109150: process (program.c:15) ``` The report shows: 1. **Error type**: "Invalid read of size 4" (4-byte read outside valid memory) 2. **Call stack at the error**: where in the code the bug happened (program.c:22, called from program.c:31) 3. **Memory details**: what address was accessed, why it's invalid ("0 bytes after a block of size 40"), and where that block was allocated (program.c:15) This information pinpoints both the bug location and its root cause (the allocation). **Line number attribution:** Debug symbols (`-g` flag) allow Valgrind to show source file names and line numbers. Without `-g`, you get only memory addresses and function names (much harder to debug). Always compile with `-g` for memcheck runs. Optimization flags can affect line attribution. At `-O3`, the compiler reorders, inlines, and eliminates code. A reported line might not be exactly where the bug occurs—it's close but not precise. At `-O0`, line attribution is accurate. **Handling "possibly lost" blocks:** Valgrind sometimes reports "possibly lost" leaks—blocks where the pointer might still exist in a register or on the stack. This is conservative error reporting. Most "possibly lost" blocks are false positives (the program is about to free them or keeps the pointer elsewhere). Focus on "definitely lost". **Common error types:** ``` Invalid read of size N -- reading past buffer end Invalid write of size N -- writing past buffer end Use of uninitialised value -- reading uninitialized memory Mismatched free/delete -- freed with free() but allocated with new (C++) Invalid free() -- double-free or freeing non-allocated memory ``` **Stack traces:** Frames at the bottom are usually in Valgrind's replacement allocator (malloc) or system libraries. Focus on frames in your own code (your source files). System library frames are context but usually not where to fix the bug. **Suppression output:** Use `--gen-suppressions=yes` to have Valgrind auto-generate suppressions for each error: ```bash valgrind --gen-suppressions=yes ./program 2>&1 | tee valgrind.log ``` This lets you selectively suppress known false positives while fixing real bugs. **Leak detection timing:** Leaks are reported at program exit. If your program crashes or is killed before exiting normally, leak detection doesn't run. Ensure the program exits cleanly: `exit(0)` or `return 0;` from main.