简体   繁体   中英

Understand memory leak types in valgrind memcheck tool

I am using Valgrind tool to understand the different types of memory leaks: Directly lost,Indirectly lost Still reachable and possibly lost. Ex1:

#include<stdio.h>
#include <stdlib.h>
main() {
    int *p, i;
     p = malloc(10*sizeof(int));
      for(i = 0;i < 10;i++)
       p[i] = i;
       //free(p);
      printf("Freed\n ");

}

LEAK SUMMARY:
==31770==    definitely lost: 0 bytes in 0 blocks
==31770==    indirectly lost: 0 bytes in 0 blocks
==31770==      possibly lost: 20 bytes in 1 blocks
==31770==    still reachable: 0 bytes in 0 blocks
==31770==         suppressed: 0 bytes in 0 blocks


eg2:
main() {
    int *p, i;
     p = malloc(10*sizeof(int));

//     printf("freed");
}

 LEAK SUMMARY:
==14950==    definitely lost: 0 bytes in 0 blocks
==14950==    indirectly lost: 0 bytes in 0 blocks
==14950==      possibly lost: 0 bytes in 0 blocks
==14950==    still reachable: 40 bytes in 1 blocks
==14950==         suppressed: 0 bytes in 0 blocks

If a uncomment the printf statement:
 LEAK SUMMARY:
==15889==    definitely lost: 40 bytes in 1 blocks
==15889==    indirectly lost: 0 bytes in 0 blocks
==15889==      possibly lost: 0 bytes in 0 blocks
==15889==    still reachable: 0 bytes in 0 blocks
==15889==         suppressed: 0 bytes in 0 blocks

Please explain me exactly about those different memory leaks.

A quick internet search leads to the following site:

http://valgrind.org/docs/manual/faq.html#faq.deflost

The details are in the Memcheck section of the user manual.

In short:

  • "definitely lost" means your program is leaking memory -- fix those leaks!

  • "indirectly lost" means your program is leaking memory in a pointer-based structure. (Eg if the root node of a binary tree is "definitely lost", all the children will be "indirectly lost".) If you fix the "definitely lost" leaks, the "indirectly lost" leaks should go away.

  • "possibly lost" means your program is leaking memory, unless you're doing unusual things with pointers that could cause them to point into the middle of an allocated block; see the user manual for some possible causes. Use --show-possibly-lost=no if you don't want to see these reports.

  • "still reachable" means your program is probably ok -- it didn't free some memory it could have. This is quite common and often reasonable. Don't use --show-reachable=yes if you don't want to see these reports.

  • "suppressed" means that a leak error has been suppressed. There are some suppressions in the default suppression files. You can ignore suppressed errors.

Update:

The difference between "definitely lost" and "still reachable" is as follows: Your memory is definitely lost if all references to it are gone and you did not free it before - the classical case of a memory leak. It is still reachable when, at the end of your program's lifetime, you did not free all memory that was dynamically allocated but there are still valid references to it, so that it could be freed .

Since all of the program's memory is freed at program termination anyway, this isn't usually a problem. However for a long running program and large memory allocations, it might be worth manually freeing those if you don't need them anymore.

Let me show you a simple example:

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

char *still_reachable;
char *definitely_lost_global;

int main()
{
    char *definitely_lost_local;

    // allocate 10 bytes of memory -> will get lost
    definitely_lost_local = malloc(10 * sizeof *definitely_lost_local);
    // allocate 20 bytes of memory -> will get lost
    definitely_lost_global = malloc(20 * sizeof *definitely_lost_global);

    definitely_lost_global = NULL;
    // Now there aren't any references to those 20 bytes anymore, so memory is lost.

    // allocate 40 bytes of memory. The global pointer has static storage duration.
    // We do not change the pointer, so the respective memory will
    // be still reachable by the end of program lifetime
    still_reachable = malloc(40 * sizeof *still_reachable);
} // scope of definitely_lost_local ends here --> 10 bytes are lost!

We can guess that 10+20 = 30 bytes will be lost in this example, while 40 bytes will be still reachable. So let's check with valgrind:

==19474== Memcheck, a memory error detector
==19474== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==19474== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==19474== Command: ./prog
==19474==
==19474==
==19474== HEAP SUMMARY:
==19474==     in use at exit: 70 bytes in 3 blocks
==19474==   total heap usage: 3 allocs, 0 frees, 70 bytes allocated
==19474==
==19474== LEAK SUMMARY:
==19474==    definitely lost: 30 bytes in 2 blocks
==19474==    indirectly lost: 0 bytes in 0 blocks
==19474==      possibly lost: 0 bytes in 0 blocks
==19474==    still reachable: 40 bytes in 1 blocks
==19474==         suppressed: 0 bytes in 0 blocks
==19474== Rerun with --leak-check=full to see details of leaked memory
==19474==
==19474== For counts of detected and suppressed errors, rerun with: -v
==19474== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Voilá, as expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM