How to Detect Memory Leaks in C?

In C, memory leaks occur when programmers allocate memory by using functions like malloc, calloc, realloc etc., but forget to deallocate the memory by using free function. In this article, we will learn how to detect memory leaks in C.

Detecting Memory Leaks in C Programs

Detecting memory leaks in C can be more challenging as C lacks the automatic memory management features or other functions that helps in smart memory management. However, several strategies and tools can help detect and prevent memory leaks in C:

Manual Techniques

Code Review and Best Practices:

  • Carefully review code to ensure every malloc, calloc, and realloc has a corresponding free.
  • Use consistent memory management patterns, such as pairing allocations and deallocations in the same scope or module.

Tracking Allocations and Deallocations:

  • Implement custom memory management functions that log allocations and deallocations to track memory usage.

The above methods are difficult to implement and maintain. So we generally use the tools like valgrind, ASan, etc.

Valgrind Tool

Valgrind is a powerful tool that can detect memory leaks, invalid memory access, and other memory-related errors. It is the most common and popular method for finding memory leaks in C.

C Program to Detect Memory Leaks using Valgrind

The below example demonstrates a simple program that causes a memory leak, and how we can detect it using Valgrind.

C
// C program causing a memory leak

#include <stdlib.h>

int main()
{
    // Allocating memory without freeing it
    int* ptr = (int*)malloc(sizeof(int));

    return 0;
}


After compilation of the above program, we can run the program using Valgrind to detect memory leaks:

valgrind --leak-check=full ./leak_example

Valgrind will report the memory leak, including the location in the source code where the leaked memory was allocated.

Sample Output

==12345== Memcheck, a memory error detector
==12345== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==12345== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==12345== Command: ./memleak
==12345==
==12345==
==12345== HEAP SUMMARY:
==12345== in use at exit: 100 bytes in 1 blocks
==12345== total heap usage: 1 allocs, 0 frees, 100 bytes allocated
==12345==
==12345== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1
==12345== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12345== by 0x108671: main (memleak.c:6)
==12345==
==12345== LEAK SUMMARY:
==12345== definitely lost: 100 bytes in 1 blocks
==12345== indirectly lost: 0 bytes in 0 blocks
==12345== possibly lost: 0 bytes in 0 blocks
==12345== still reachable: 0 bytes in 0 blocks
==12345== suppressed: 0 bytes in 0 blocks
==12345==
==12345== For counts of detected and suppressed errors, rerun with: -v
==12345== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)