简体   繁体   中英

Avoiding memory leaks in POSIX thread

I started to learn about POSIX threads and about free ing memory from function called through pthread_create which has inside a malloc call. So I came to the following program:

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

void *foo( void *vargp );

int main( void )
{
    pthread_t thread_id[5];
    const char *msg = "Hello\n";
    char **ptr = NULL;
    printf("Before Thread\n");

    for( int i = 0 ; i < 5 ; i++ )
    {
        pthread_create(&thread_id[i], NULL, foo, (void*)msg);
    }

    for( int i = 0 ; i < 5 ; i++ )
    {
        pthread_join(thread_id[i], ( void* )&ptr );
        free( ptr );
    }

    printf("After Thread\n");
}

void *foo( void *vargp )
{
    char *ptr = malloc( 256 * sizeof( * ptr ) );
    strcpy( ptr, (char*)vargp );
    printf("The message is: %s \n", ptr );
    pthread_exit( ptr );
}

after I run valgrind :

valgrind --leak-check=full --track-origins=yes --show-leak-kinds=all ./Demo

And I get the following Output, which seems to be OK with the memory and there is no leak reported by valgrind :

==5255== Memcheck, a memory error detector
==5255== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==5255== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==5255== Command: ./Demo
==5255== 
Before Thread
The message is: Hello

The message is: Hello

The message is: Hello

The message is: Hello

The message is: Hello

After Thread
==5255== 
==5255== HEAP SUMMARY:
==5255==     in use at exit: 0 bytes in 0 blocks
==5255==   total heap usage: 16 allocs, 16 frees, 5,358 bytes allocated
==5255== 
==5255== All heap blocks were freed -- no leaks are possible
==5255== 
==5255== For counts of detected and suppressed errors, rerun with: -v
==5255== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Now here is something which I do not understand, if I remove de \\n from here:

const char *msg = "Hello\n";

And I compile and run valgrind again, I get:

==5279== Memcheck, a memory error detector
==5279== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==5279== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==5279== Command: ./Demo
==5279== 
Before Thread
The message is: Hello 
The message is: Hello 
The message is: Hello 
The message is: Hello 
The message is: Hello 
After Thread
==5279== 
==5279== HEAP SUMMARY:
==5279==     in use at exit: 1,638 bytes in 4 blocks
==5279==   total heap usage: 16 allocs, 12 frees, 5,358 bytes allocated
==5279== 
==5279== 36 bytes in 1 blocks are still reachable in loss record 1 of 4
==5279==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5279==    by 0x401D329: strdup (strdup.c:42)
==5279==    by 0x4018656: _dl_load_cache_lookup (dl-cache.c:315)
==5279==    by 0x4009382: _dl_map_object (dl-load.c:2255)
==5279==    by 0x4014EE3: dl_open_worker (dl-open.c:235)
==5279==    by 0x53C92DE: _dl_catch_exception (dl-error-skeleton.c:196)
==5279==    by 0x40147C9: _dl_open (dl-open.c:605)
==5279==    by 0x53C83AC: do_dlopen (dl-libc.c:96)
==5279==    by 0x53C92DE: _dl_catch_exception (dl-error-skeleton.c:196)
==5279==    by 0x53C936E: _dl_catch_error (dl-error-skeleton.c:215)
==5279==    by 0x53C84D8: dlerror_run (dl-libc.c:46)
==5279==    by 0x53C84D8: __libc_dlopen_mode (dl-libc.c:195)
==5279==    by 0x5055DEA: pthread_cancel_init (unwind-forcedunwind.c:52)
==5279== 
==5279== 36 bytes in 1 blocks are still reachable in loss record 2 of 4
==5279==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5279==    by 0x400C3E7: _dl_new_object (dl-object.c:163)
==5279==    by 0x40069A4: _dl_map_object_from_fd (dl-load.c:943)
==5279==    by 0x4008FFB: _dl_map_object (dl-load.c:2389)
==5279==    by 0x4014EE3: dl_open_worker (dl-open.c:235)
==5279==    by 0x53C92DE: _dl_catch_exception (dl-error-skeleton.c:196)
==5279==    by 0x40147C9: _dl_open (dl-open.c:605)
==5279==    by 0x53C83AC: do_dlopen (dl-libc.c:96)
==5279==    by 0x53C92DE: _dl_catch_exception (dl-error-skeleton.c:196)
==5279==    by 0x53C936E: _dl_catch_error (dl-error-skeleton.c:215)
==5279==    by 0x53C84D8: dlerror_run (dl-libc.c:46)
==5279==    by 0x53C84D8: __libc_dlopen_mode (dl-libc.c:195)
==5279==    by 0x5055DEA: pthread_cancel_init (unwind-forcedunwind.c:52)
==5279== 
==5279== 384 bytes in 1 blocks are still reachable in loss record 3 of 4
==5279==    at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5279==    by 0x4011E85: _dl_check_map_versions (dl-version.c:274)
==5279==    by 0x401524B: dl_open_worker (dl-open.c:284)
==5279==    by 0x53C92DE: _dl_catch_exception (dl-error-skeleton.c:196)
==5279==    by 0x40147C9: _dl_open (dl-open.c:605)
==5279==    by 0x53C83AC: do_dlopen (dl-libc.c:96)
==5279==    by 0x53C92DE: _dl_catch_exception (dl-error-skeleton.c:196)
==5279==    by 0x53C936E: _dl_catch_error (dl-error-skeleton.c:215)
==5279==    by 0x53C84D8: dlerror_run (dl-libc.c:46)
==5279==    by 0x53C84D8: __libc_dlopen_mode (dl-libc.c:195)
==5279==    by 0x5055DEA: pthread_cancel_init (unwind-forcedunwind.c:52)
==5279==    by 0x5055FD3: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126)
==5279==    by 0x5053F0F: __pthread_unwind (unwind.c:121)
==5279== 
==5279== 1,182 bytes in 1 blocks are still reachable in loss record 4 of 4
==5279==    at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5279==    by 0x400C100: _dl_new_object (dl-object.c:73)
==5279==    by 0x40069A4: _dl_map_object_from_fd (dl-load.c:943)
==5279==    by 0x4008FFB: _dl_map_object (dl-load.c:2389)
==5279==    by 0x4014EE3: dl_open_worker (dl-open.c:235)
==5279==    by 0x53C92DE: _dl_catch_exception (dl-error-skeleton.c:196)
==5279==    by 0x40147C9: _dl_open (dl-open.c:605)
==5279==    by 0x53C83AC: do_dlopen (dl-libc.c:96)
==5279==    by 0x53C92DE: _dl_catch_exception (dl-error-skeleton.c:196)
==5279==    by 0x53C936E: _dl_catch_error (dl-error-skeleton.c:215)
==5279==    by 0x53C84D8: dlerror_run (dl-libc.c:46)
==5279==    by 0x53C84D8: __libc_dlopen_mode (dl-libc.c:195)
==5279==    by 0x5055DEA: pthread_cancel_init (unwind-forcedunwind.c:52)
==5279== 
==5279== LEAK SUMMARY:
==5279==    definitely lost: 0 bytes in 0 blocks
==5279==    indirectly lost: 0 bytes in 0 blocks
==5279==      possibly lost: 0 bytes in 0 blocks
==5279==    still reachable: 1,638 bytes in 4 blocks
==5279==         suppressed: 0 bytes in 0 blocks
==5279== 
==5279== For counts of detected and suppressed errors, rerun with: -v
==5279== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

So I have 3 Question:

1) - did I free() the malloc correctly

2) - Why I get that output if I remove \\n

3) - Do I have (must) to free() that memory inside foo ?

To me looks like my Program (somehow) is UB .

1) yes you have correctly free'd the memory

2) the OS internally sometime does some bizarre things that valgrind does not understand. If you do not want to see these messages then you should suppressing rules ( http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress )

3) no, as long as you free the memory before the end of the process, it is not a memory leak

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