Проблема утечки памяти с malloc в C

Я относительно новичок в C и malloc. Я написал lib с основными функциями, которые я наполняю новыми по ходу работы и которые я использую для других небольших проектов, подобных этому.

Я услышал о Valgrind и решил проверить с ним свою программу, но не могу понять, почему у меня так много leaks. Мне кажется, что все мои mallocs защищены с помощью if (line == NULL) при использовании функций, использующих сами malloc.

Не могли бы вы вернуть меня сюда?

static char *concator(char *s1, char *s2, size_t len)
{
    char    *line;
    size_t  size;

    if (!s1 || !s2)
        return (NULL);
    size = strlen(s1) + strlen(s2);
    line = (char*)memalloc(sizeof(char) * size + 1);
    if (line == NULL)
        return (NULL);
    strcpy(line, s1);
    strncat(line, s2, len);
    strdel(&s1);
    return (line);
}

int line_reader(const int fd, char **line)
{
    static char buf[BUFF_SIZE];
    char        *pos;
    int         ret;

    if (fd < 0 || !line || read(fd, buf, 0) < 0 || BUFF_SIZE < 1)
        return (-1);
    *line = strnew(0);
    if (line == NULL)
        return (-1);
    while (1)
    {
        pos = strchr(buf, '\n');
        if (pos)
        {
            *line = concator(*line, buf, pos - buf);
            if (line == NULL)
                return (-1);
            strncpy(buf, &buf[pos - buf + 1], BUFF_SIZE - (pos - buf));
            return (1);
        }
        *line = concator(*line, buf, BUFF_SIZE);
        if (line == NULL)
            return (-1);
        ret = read(fd, buf, BUFF_SIZE);
        buf[ret] = '\0';
        if (!ret)
            return ((**line) ? 1 : 0);
    }
}

Где в вашем коде вы free размещаете выделенную память?

Chris Turner 26.11.2018 18:53

Valgrind, вероятно, сообщает вам (включите его отчет здесь), что вы не освобождаете выделенную память до завершения программы.

500 - Internal Server Error 26.11.2018 18:53

@ChrisTurner Как мне получить free, что мне нужно для return?

Wizzardzz 26.11.2018 18:55

Вы освободите его после того, как закончите пользоваться им, а не когда вернете.

Robert Harvey 26.11.2018 18:56

вы не используете realloc для увеличения размера *line - вы продолжаете выделять для него новые блоки памяти и теряете старые.

Chris Turner 26.11.2018 19:02

Я почти уверен, что strncpy(buf, &buf[pos - buf + 1], BUFF_SIZE - (pos - buf)); - это UB (перекрывающиеся исходные / целевые буферы).

melpomene 26.11.2018 19:04

@melpomene Как я могу быть уверен?

Wizzardzz 26.11.2018 19:09

@RobertHarvey Не могли бы вы мне подсказать, где это будет расположено в моем коде?

Wizzardzz 26.11.2018 19:10

После возвращения. Вы сами сказали: вы не сможете вернуть его, если сначала освободите.

Robert Harvey 26.11.2018 19:11

@RobertHarvey Я думал, что ничего не было сделано после return.

Wizzardzz 26.11.2018 19:11

Ну, вы делаете что-то с возвращенным значением, не так ли? Иначе какой смысл его возвращать?

Robert Harvey 26.11.2018 19:11

@RobertHarvey Абсолютно да

Wizzardzz 26.11.2018 19:12

В ПОРЯДКЕ. Итак, когда вы закончите с этим, free это.

Robert Harvey 26.11.2018 19:13

Похоже, путаница связана с тем, когда вы освободите его. Этого точно не будет, пока вы не вернете переменную. Это может быть какая-то другая функция, которая использует эту переменную. Когда вы размещаете данные внутри функции и возвращаете их, ответственность за освобождение данных ложится на того, кто вызвал эту функцию.

ahota 26.11.2018 19:19

@Wizzardzz Я не знаю, это твой код. Части источника / цели перекрываются или нет?

melpomene 26.11.2018 20:18

Примечание: || BUFF_SIZE < 1 не имеет никакого смысла после read(fd, buf, 0).

chux - Reinstate Monica 26.11.2018 21:48
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
16
89
1

Ответы 1

Бесплатно line после того, как вы его используете, например:

char* line;
int rc = line_reader(fd, &line);
if (rc > 0)
{
    //use line
    printf("%s\n", line);
    //then free it
    free(line);
} 

Это должно исправить проблемы с утечкой памяти, о которых сообщает valgrind. Однако следите за другими ошибками, упомянутыми в комментариях.

Другие вопросы по теме