valgrind(1)

Development tool

Runs your program while watching every memory access: invalid reads, uninitialized values, blocks that are never freed.

Synopsis
valgrind [options] program [arguments]

Description

Valgrind runs your program on a simulated processor. Its default tool, Memcheck, intercepts every read, every write, every malloc and every free. It reports accesses outside the allocated blocks, uses of values that were never initialized, double frees, and at the end the memory still allocated. The program runs much more slowly; that is the price of this monitoring.

Compile with -g: without it, the reports give addresses instead of file names and line numbers.

Useful options

OptionEffect
--leak-check=fulldetails each leak with the line that allocated the block
--show-leak-kinds=allalso shows the memory still reachable at exit
--track-origins=yestells you where an uninitialized value comes from
-qprints only the errors

Example

leak.c
#include <stdlib.h>#include <string.h>
int main(void){    char *copy = malloc(16);
    strcpy(copy, "leak");    return 0;}
Terminal
$ gcc -g leak.c -o leak$ valgrind --leak-check=full ./leak==14== Memcheck, a memory error detector==14== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.==14== Using Valgrind-3.24.0 and LibVEX; rerun with -h for copyright info==14== Command: ./leak==14== ==14== ==14== HEAP SUMMARY:==14==     in use at exit: 16 bytes in 1 blocks==14==   total heap usage: 1 allocs, 0 frees, 16 bytes allocated==14== ==14== 16 bytes in 1 blocks are definitely lost in loss record 1 of 1==14==    at 0x488545C: malloc (vg_replace_malloc.c:446)==14==    by 0x400653: main (leak.c:6)==14== ==14== LEAK SUMMARY:==14==    definitely lost: 16 bytes in 1 blocks...==14== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

The number at the start of each line is the process ID. The 16-byte block allocated on line 6 was never freed, and no pointer refers to it anymore: it is “definitely lost”.

Pitfalls

  • Valgrind only sees the path that actually runs. A test that does not go through the faulty code reports nothing.

  • It does not watch overruns inside the stack, such as an int t[5] read at t[5]. For those, compile with -fsanitize=address.

  • On recent versions of macOS, Valgrind is not officially available. A Linux container, WSL or the terminal of a Grademe exercise will do.

C

read_the_leak

Fix build_path, which returns the right path but leaks one block per call: read the leak report, then free the block it borrowed.

Open the exercise

Now write it yourself.