Как исправить «утечку памяти» в C - PullRequest
0 голосов
/ 02 июня 2019

Я пишу программу на C, динамически выделяемую

Может кто-нибудь объяснить, как исправить эту утечку памяти в "goto"

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

int main()
{
    printf("start main\n");
    char *f = NULL;
    L1:
        f = (char *)malloc(10);
        if (f == NULL)
            return -1;
        printf("body lebel\n");
        f = "A";
        if (f == "B") {
            free(f);
            goto L1;
        }

      return 0;

 return 0;
} 

valgrind --leak-check=full ./a.out,

Вывод:

==7217== HEAP SUMMARY:
==7217==     in use at exit: 10 bytes in 1 blocks
==7217==   total heap usage: 2 allocs, 1 frees, 1,034 bytes 
allocated

1 Ответ

1 голос
/ 02 июня 2019

Первый

f = "A";

назначает указатель на символ f для указания на "A", то есть const char*, который находится где-то в образе процесса.Это полностью лишает вас памяти, выделенной вами malloc.Чтобы скопировать строку "A" в память, на которую указывает f, вам нужно написать что-то вроде

strcpy(f, "A");

или

strncpy(f, "A", 10);

с оговоркой, что strcpy можетпереполнение буфера, выделенного для f, и strncpy может оставить его без завершения нуля.

Во-вторых, вы можете освободить f только внутри оператора if, прежде чем перейти к L1.Чтобы освободить f до выхода из программы, вы также должны написать free(f) до return 0.

В-третьих, f == "B" проверяет, указывает ли f значение const char * * "B", не совпадает ли его содержимое с "B".В вашей программе это всегда ложно, поскольку вы присваиваете "A" непосредственно перед тем, как сравнивать.Вам необходимо использовать такую ​​функцию, как strcmp для строк с нулевым символом в конце или memcmp для строк, не заканчивающихся нулем.

Можно также переместить первые free в началолейбл, так что вам не нужно обязательно освобождать его перед прыжком, так как free(NULL) ничего не делает.Также в интересах потомков вы должны объявить "A" и "B" в качестве переменных и переместить постоянную 10 в переменную, чтобы предотвратить нарушения памяти в будущем:

int main()
{
    const char a_str[] = "A";
    const char b_str[] = "B";
    size_t buffer_size = 10;
    printf("start main\n");
    char *f = NULL;
    L1:
        free(f);
        f = (char *)malloc(buffer_size);
        if (f == NULL)
            return -1;
        printf("body lebel\n");
        if (buffer_size < sizeof(a_str)) {
            printf("Buffer too small for %s\n", a_str);
            exit(1);
        }
        memcpy(f, a_str, sizeof(a_str));
        if (buffer_size < sizeof(b_str)) {
            printf("Buffer too small for comparison with %s\n", b_str);
            exit(1);
        }
        if (!memcmp(f, b_str, sizeof(b_str)) {
            goto L1;
        }
    free(f);

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...