@COUT_man

Как разобраться с выводом valgrind?

Подскажите, пожалуйста, как разобраться с результатом работы valgrind. Совершенно не могу понять где проблема. У меня или в программе. Хотя я более чем уверен, что виноват мой код. Но я понятия не имею, где именно я напортачил...

По заданию должен описать функцию get_next_line.
Сделал её реализацию. Но при прогоне с помощью программы для тестирования натыкаюсь на утечку памяти:

==890== 2 bytes in 1 blocks are definitely lost in loss record 1 of 1
==890==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==890==    by 0x407335: get_next_line (get_next_line.c:31)
==890==    by 0x402C86: gnl(int, char const*) (gnl.cpp:20)
==890==    by 0x405272: main (mandatory.cpp:41)


Строка на которую ссылается valgrind
31result = (char *)malloc(sizeof(char) * 2);
32    if (!result)
33    {
34       free (result);
35        return (0);
36    }


Конечно я понимаю, что по хорошему счёту нужно освобождать память после использования malloс, но встаёт вопрос сохранения данных. Я попробовал сделать костыль в виде передаче значения и выполнить очистку с помощью free().
изобразил я что-то типа:
getresult = result;
    free(result);
    return (getresult);

И получил новую порцию оплеух. Не смотря на то, что сами тесты проходят успешно.
==922== Invalid free() / delete / delete[] / realloc()
==922==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==922==    by 0x402CDB: gnl(int, char const*) (gnl.cpp:25)
==922==    by 0x4054AB: main (mandatory.cpp:46)
==922==  Address 0x4db6ce0 is 0 bytes inside a block of size 2 free'd
==922==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==922==    by 0x40745B: get_next_line (get_next_line.c:70)
==922==    by 0x402C86: gnl(int, char const*) (gnl.cpp:20)
==922==    by 0x4054AB: main (mandatory.cpp:46)
==922==  Block was alloc'd at
==922==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==922==    by 0x40755B: ft_strjoin (get_next_line_utils.c:40)
==922==    by 0x407431: get_next_line (get_next_line.c:65)
==922==    by 0x402C86: gnl(int, char const*) (gnl.cpp:20)
==922==    by 0x4054AB: main (mandatory.cpp:46)


сам код:
char    *get_next_line(int fd)
{
    char *getresult;
    char    *result;
    char    *readline;
    char    symb;
    int readbyte;
    int i;
    int all_readbyte;
    char flag;

    all_readbyte = 0;
    if (!fd && BUFFER_SIZE <= 0)
        return (0);
    flag = 'n';
    readbyte = read(fd, &symb, 1);
    all_readbyte++;
    result = (char *)malloc(sizeof(char) * 2);
    if (!result)
    {
        free (result);
        return (0);
    }
    result[0] = '\0';
    result[1] = '\0';
    if (readbyte <= 0)
        return (0);
    while (flag != 'y')
    {
        i = 0;
        readline = (char *)malloc(sizeof(char) * BUFFER_SIZE + 1);
        if (!readline)
            return (0);
        while (i < BUFFER_SIZE)
        {
            readline[i++] = symb;
            if (symb == '\n' || symb == '\0' || readbyte <= 0 || !symb)
            {
                flag = 'y';
                break;
            }
            readbyte = read(fd, &symb, 1);
            if (readbyte <= 0)
            {
                flag = 'y';
                break;
            }
            all_readbyte++;
        }
        readline[i] = '\0';
        result = ft_strjoin(result, readline);
        free (readline);
        if (readbyte == 0)
        {
            getresult = result;
            free(result);
            return (getresult);
        }
    }
    if (all_readbyte == 1)
        result[0] = symb;
    getresult = result;
    free(result);
    return (getresult);
}
  • Вопрос задан
  • 194 просмотра
Решения вопроса 1
shurshur
@shurshur
Сисадмин, просто сисадмин...
При попадании в блок:
if (!result)
память реально НЕ выделена и free от неё - это попытка освободить память по адресу NULL. Разумеется, это не будет работать.

upd: Прочитал вопрос ещё раз внимательнее. Надо не забывать делать free в конечном месте использования этого result:

result = get_next_line();<br>
...do_something_with_result...<br>
free(result);


Иначе да, при каждом вызове get_next_line будет выделяться новый блок на 2 байта.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы