← thecodex.expert · The Codex Family of Knowledge
C

Memory Safety Tools

A buffer overflow or a leaked allocation can compile perfectly and even run without any visible symptom for a long time — these tools are how you actually find out it’s there before it becomes a real production bug.

C17 / C23 Valgrind or AddressSanitizer Last verified:
Canonical Definition

Valgrind's Memcheck tool runs a compiled program inside a simulated CPU, intercepting every memory access to catch leaks, use-after-free, reading uninitialized memory, and heap buffer overflows — at a genuine, often significant runtime performance cost, since everything is emulated. Memcheck's overflow detection is specifically a heap strength: it puts redzones around malloc'd blocks, so it does not reliably catch a stack- or global-array overrun the same way (verified directly: a plain stack array read past its bounds produced zero Memcheck errors on a run where AddressSanitizer caught the identical bug immediately). AddressSanitizer (ASan) takes a different approach: the compiler instruments the code directly at compile time with a -fsanitize=address flag, adding redzones around heap, stack, AND global memory alike, catching a broader range of overflow bugs with far less runtime overhead than Valgrind, at the cost of needing to recompile the program specifically for that instrumented build.

Valgrind: catching a leak that compiled cleanly

This program compiles and runs with no visible error at all — the leak is completely silent until a tool like Valgrind actually points it out.

Cleaky.c
int main(void) {
    int *data = malloc(100 * sizeof(int));
    data[0] = 42;
    printf("%d\n", data[0]);
    return 0;   // missing free(data) — a real leak, but the program runs "fine"
}
Shellterminal
$ gcc -g -o leaky leaky.c
$ valgrind --leak-check=full ./leaky
==12345== Memcheck, a memory error detector
==12345== Command: ./leaky
==12345==
42
==12345==
==12345== HEAP SUMMARY:
==12345==     in use at exit: 400 bytes in 1 blocks
==12345==   total heap usage: 2 allocs, 1 frees, 4,496 bytes allocated
==12345==
==12345== 400 bytes in 1 blocks are definitely lost in loss record 1 of 1
==12345==    at 0x4846828: malloc (vgpreload_memcheck-amd64-linux.so)
==12345==    by 0x10917E: main (leaky.c:4)
==12345==
==12345== LEAK SUMMARY:
==12345==    definitely lost: 400 bytes in 1 blocks
==12345==
==12345== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
# real captured output, trimmed -- notice the leak trace has TWO frames: Valgrind's
# own malloc interceptor, then the actual call site (main, leaky.c) one level up

AddressSanitizer: faster, compiler-integrated

ASan catches the exact moment of an out-of-bounds access with a precise stack trace, and typically runs several times faster than the equivalent Valgrind check — the tradeoff is needing a specially-instrumented build rather than running any existing binary unmodified. This particular bug is also a case where the two tools genuinely aren't interchangeable: it's a stack array, and Valgrind alone (verified directly, no ASan) reports zero errors for it — Memcheck's overflow detection is built around heap redzones, so a stack overrun like this one sails right past it.

Coverflow.c
int main(void) {
    int arr[5] = {1, 2, 3, 4, 5};
    printf("%d\n", arr[10]);   // out of bounds — undefined behavior
    return 0;
}
Shellterminal
$ gcc -fsanitize=address -g -o overflow overflow.c
$ ./overflow
==12345==ERROR: AddressSanitizer: stack-buffer-overflow ...
    #0 in main overflow.c:3   # precise line, immediately when it happens

Why running these regularly matters

Both tools catch bugs that compile with zero warnings and often produce no visible symptom under normal testing — the memory corruption might not crash the program until much later, in a completely unrelated part of the code, making it extremely difficult to trace back without one of these tools. Running Memcheck or ASan as a routine part of testing, not just when something visibly breaks, catches these issues while they're still easy to localize.

Sources

1
Valgrind Developers. Valgrind Quick Start, valgrind.org/docs/manual/quick-start.html, and Clang/GCC AddressSanitizer documentation.