Skip to content

Find C/C++ memory leak with valgrind on Linux

Install valgrind

sudo apt install valgrind  # Ubuntu, Debian, etc.
sudo yum install valgrind  # RHEL, CentOS, Fedora, etc.

Find memory leak

#include <stdlib.h>
int main()
{
    int *array = malloc(sizeof(int));
    return 0;
}
gcc -g -o memory-leak memory-leak.c
valgrind --tool=memcheck --leak-check=full ./memory-leak
==43199== Memcheck, a memory error detector
==43199== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==43199== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==43199== Command: ./memory-leak
==43199== 
==43199== 
==43199== HEAP SUMMARY:
==43199==     in use at exit: 4 bytes in 1 blocks
==43199==   total heap usage: 1 allocs, 0 frees, 4 bytes allocated
==43199== 
==43199== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==43199==    at 0x483877F: malloc (vg_replace_malloc.c:307)
==43199==    by 0x109146: main (m-l.c:4)
==43199== 
==43199== LEAK SUMMARY:
==43199==    definitely lost: 4 bytes in 1 blocks
==43199==    indirectly lost: 0 bytes in 0 blocks
==43199==      possibly lost: 0 bytes in 0 blocks
==43199==    still reachable: 0 bytes in 0 blocks
==43199==         suppressed: 0 bytes in 0 blocks
==43199== 
==43199== For lists of detected and suppressed errors, rerun with: -s
==43199== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Find illegal read write

#include <stdlib.h>
int main()
{
  int *ptr=0;
  (*ptr)=33;
  return 0;
} 
==43241== Memcheck, a memory error detector
==43241== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==43241== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==43241== Command: ./memory-leak
==43241== 
==43241== Invalid write of size 4
==43241==    at 0x109135: main (m-l.c:5)
==43241==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==43241== 
==43241== 
==43241== Process terminating with default action of signal 11 (SIGSEGV)
==43241==  Access not within mapped region at address 0x0
==43241==    at 0x109135: main (m-l.c:5)
==43241==  If you believe this happened as a result of a stack
==43241==  overflow in your program's main thread (unlikely but
==43241==  possible), you can try to increase the size of the
==43241==  main thread stack using the --main-stacksize= flag.
==43241==  The main thread stack size used in this run was 8388608.
==43241== 
==43241== HEAP SUMMARY:
==43241==     in use at exit: 0 bytes in 0 blocks
==43241==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==43241== 
==43241== All heap blocks were freed -- no leaks are possible
==43241== 
==43241== For lists of detected and suppressed errors, rerun with: -s
==43241== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault

Find invalid pointer

#include <stdlib.h>

int main()
{
    char *x = malloc(10);
    x[10] = 'a';
    return 0;
}
==43275== Memcheck, a memory error detector
==43275== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==43275== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==43275== Command: ./memory-leak
==43275== 
==43275== Invalid write of size 1
==43275==    at 0x109153: main (m-l.c:6)
==43275==  Address 0x4a1604a is 0 bytes after a block of size 10 alloc'd
==43275==    at 0x483877F: malloc (vg_replace_malloc.c:307)
==43275==    by 0x109146: main (m-l.c:5)
==43275== 
==43275== 
==43275== HEAP SUMMARY:
==43275==     in use at exit: 10 bytes in 1 blocks
==43275==   total heap usage: 1 allocs, 0 frees, 10 bytes allocated
==43275== 
==43275== 10 bytes in 1 blocks are definitely lost in loss record 1 of 1
==43275==    at 0x483877F: malloc (vg_replace_malloc.c:307)
==43275==    by 0x109146: main (m-l.c:5)
==43275== 
==43275== LEAK SUMMARY:
==43275==    definitely lost: 10 bytes in 1 blocks
==43275==    indirectly lost: 0 bytes in 0 blocks
==43275==      possibly lost: 0 bytes in 0 blocks
==43275==    still reachable: 0 bytes in 0 blocks
==43275==         suppressed: 0 bytes in 0 blocks
==43275== 
==43275== For lists of detected and suppressed errors, rerun with: -s
==43275== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

Find uninitialised variables

#include <stdlib.h>
#include <stdio.h>
int main()
{
  int number; //Should be initialized (i.e. to zero).
  if (number==0)
  {
    printf("number is zero");
  }

  return 0;
} 
==43304== Memcheck, a memory error detector
==43304== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==43304== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==43304== Command: ./memory-leak
==43304== 
==43304== Conditional jump or move depends on uninitialised value(s)
==43304==    at 0x109141: main (m-l.c:6)
==43304== 
number is zero==43304== 
==43304== HEAP SUMMARY:
==43304==     in use at exit: 0 bytes in 0 blocks
==43304==   total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==43304== 
==43304== All heap blocks were freed -- no leaks are possible
==43304== 
==43304== Use --track-origins=yes to see where uninitialised values come from
==43304== For lists of detected and suppressed errors, rerun with: -s
==43304== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Find illegal memory frees

#include <stdlib.h>
#include <stdio.h>
int main()
{
  int * ptr=malloc(4);
  free(ptr);
  ptr++; //To mismatch 
  free(ptr);  
  return 0;
} 
==43329== Memcheck, a memory error detector
==43329== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==43329== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==43329== Command: ./memory-leak
==43329== 
==43329== Invalid free() / delete / delete[] / realloc()
==43329==    at 0x48399AB: free (vg_replace_malloc.c:538)
==43329==    by 0x109177: main (m-l.c:8)
==43329==  Address 0x4a16044 is 0 bytes after a block of size 4 free'd
==43329==    at 0x48399AB: free (vg_replace_malloc.c:538)
==43329==    by 0x109166: main (m-l.c:6)
==43329==  Block was alloc'd at
==43329==    at 0x483877F: malloc (vg_replace_malloc.c:307)
==43329==    by 0x109156: main (m-l.c:5)
==43329== 
==43329== 
==43329== HEAP SUMMARY:
==43329==     in use at exit: 0 bytes in 0 blocks
==43329==   total heap usage: 1 allocs, 2 frees, 4 bytes allocated
==43329== 
==43329== All heap blocks were freed -- no leaks are possible
==43329== 
==43329== For lists of detected and suppressed errors, rerun with: -s
==43329== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Reference

  • http://www.it.uc3m.es/pbasanta/asng/course_notes/memory_profiler_en.html#memcheck_tool
  • https://www.cprogramming.com/debugging/valgrind.html

Disclaimer
  1. License under CC BY-NC 4.0
  2. Copyright issue feedback me#imzye.me, replace # with @
  3. Not all the commands and scripts are tested in production environment, use at your own risk
  4. No privacy information is collected here
Try my iOS App