Предотвращение утечек памяти в потоке POSIX - PullRequest
0 голосов
/ 29 октября 2018

Я начал узнавать о потоках POSIX и о free памяти из функции, вызываемой через pthread_create, которая имеет внутри вызова malloc. Поэтому я пришел к следующей программе:

#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 );
}

после запуска valgrind:

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

И я получаю следующий вывод, который, кажется, в порядке с памятью, и утечка не сообщается 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)

Теперь вот что-то, чего я не понимаю, если я удалю де \n отсюда:

const char *msg = "Hello\n";

И я снова компилирую и запускаю valgrind, получаю:

==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)

Итак, у меня есть 3 вопроса:

1) - правильно ли я free() malloc

2) - Почему я получаю этот вывод, если я удаляю \n

3) - Есть ли у меня (обязательно) до free() эта память внутри foo?

Мне кажется, что моя Программа (как-то) UB.

1 Ответ

0 голосов
/ 29 октября 2018

1) да, вы правильно освободили память

2) иногда внутренняя операционная система делает некоторые странные вещи, которые не понимает valgrind. Если вы не хотите видеть эти сообщения, вам следует подавить правила (http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress)

3) нет, если вы освобождаете память до окончания процесса, это не утечка памяти

...