Here is a program that calls malloc but not free:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    char *s;

    s = malloc(26); // the culprint 

    return 0;
}

With no extra arguments, valgrind will not look for this error.

But if we turn on --leak-check=yes or --tool=memcheck, it will complain and display the lines responsible for those memory leaks if the program was compiled in debug mode:

$ valgrind -q --leak-check=yes ./missing_free
==4776== 26 bytes in 1 blocks are definitely lost in loss record 1 of 1
==4776==    at 0x4024F20: malloc (vg_replace_malloc.c:236)
==4776==    by 0x80483F8: main (missing_free.c:9)
==4776==

If the program is not compiled in debug mode (for example with the -g flag in GCC) it will still show us where the leak happened in terms of the relevant function, but not the lines.

This lets us go back and look at what block was allocated in that line and try to trace forward to see why it wasn’t freed.