Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory not freed but still reachable, is it leaking?

By checking with valgrind, I see that 5 blocks of memory were not freed after terminating my program, but they are still reachable. Do I need to be bothered by it?

And how it happens?

zhanwu@gelata:~/sandbox$ valgrind ./a.out
==2430== Memcheck, a memory error detector
==2430== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==2430== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==2430== Command: ./a.out
==2430== 
Hello world!
Thread1 returns 1
Thread2 returns 10
Thread3 returns 10
==2430== 
==2430== HEAP SUMMARY:
==2430==     in use at exit: 1,590 bytes in 5 blocks
==2430==   total heap usage: 14 allocs, 9 frees, 2,442 bytes allocated
==2430== 
==2430== LEAK SUMMARY:
==2430==    definitely lost: 0 bytes in 0 blocks
==2430==    indirectly lost: 0 bytes in 0 blocks
==2430==      possibly lost: 0 bytes in 0 blocks
==2430==    still reachable: 1,590 bytes in 5 blocks
==2430==         suppressed: 0 bytes in 0 blocks
==2430== Rerun with --leak-check=full to see details of leaked memory
==2430== 
==2430== For counts of detected and suppressed errors, rerun with: -v
==2430== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)

Below is my code, what can I do to free those 5 blocks if I intend to?

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

pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;

void* myfunction(void *ptr)
{
    static int n_call = 0;
    int *retval = malloc(sizeof(int));

    pthread_mutex_lock( &mutex1 );
    n_call++;
    *retval = n_call;
    pthread_mutex_unlock( &mutex1 );

    if(n_call < 2)
    {
        char *msg;
        msg = (char *)ptr;
        printf("%s\n", msg);

        return retval;
    }
    else
    {
        *retval = 10;
        pthread_exit(retval);
    }
}

int main(int argc, char *argv[])
{
    pthread_t t1, t2, t3;

    char *msg = "Hello world!";
    pthread_create(&t1, NULL, myfunction, (void *)msg);
    pthread_create(&t2, NULL, myfunction, (void *)msg);
    pthread_create(&t3, NULL, myfunction, (void *)msg);

    int **s1 = malloc(sizeof(int*));
    int **s2 = malloc(sizeof(int*));
    int **s3 = malloc(sizeof(int*));

    pthread_join(t1, (void **)s1);
    pthread_join(t2, (void **)s2);
    pthread_join(t3, (void **)s3);

    printf("Thread1 returns %d\n", **s1);
    printf("Thread2 returns %d\n", **s2);
    printf("Thread3 returns %d\n", **s3);

    free(*s1);
    free(*s2);
    free(*s3);

    free(s1);
    free(s2);
    free(s3);

    return 0;
}
like image 553
zhanwu Avatar asked Oct 25 '11 07:10

zhanwu


People also ask

Is reachable memory a leak?

"possibly lost" means your program is probably leaking memory, unless you're doing funny things with pointers. "still reachable" means your program is probably ok -- it didn't free some memory it could have.

What does it mean if memory is still reachable?

The memory is still reachable, so the program could still be using it. In theory, you could free it at the end of the program, but all memory is freed at the end of the program anyway. Although still reachable memory isn't a real issue in theory, you might still want to look into it.

When can you tell memory leak will occur?

A memory leak starts when a program requests a chunk of memory from the operating system for itself and its data. As a program operates, it sometimes needs more memory and makes an additional request.

How do memory leaks occur?

Memory leak occurs when programmers create a memory in heap and forget to delete it. The consequences of memory leak is that it reduces the performance of the computer by reducing the amount of available memory.


2 Answers

No it is not a memory leak.
It means your program still has reference to memory that will freed later.

Valgrind FAQ differentiates between different messages as follows:

With Memcheck's memory leak detector, what's the difference between "definitely lost", "indirectly lost", "possibly lost", "still reachable", and "suppressed"?

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. (E.g. 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 funny things with pointers. This is sometimes reasonable.
    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.

like image 101
Alok Save Avatar answered Oct 05 '22 09:10

Alok Save


It depends.

It may well be a real leak, and it might not. But either way you should fix it.

If you allocate a buffer and keep it around all the way to the end of the program, technically it's a leak, but it doesn't matter - you only allocate one buffer, and it's basically permanent.

On the other hand perhaps you are allocating a buffer in a way that it's done just once in your test code, but later with the real code it might get allocated more than once - then you have a leak.

So it's best to fix them all.

like image 42
Ariel Avatar answered Oct 05 '22 09:10

Ariel