переменная char * не освободится? - PullRequest
0 голосов
/ 05 ноября 2019

, поэтому я кодирую функцию, которая берет строку из файла и печатает ее, проблема в том, что я не могу освободить переменную char *, вот код

int main()
{
    char *line; 
    int fd;

    fd = open("text.txt", O_RDONLY);
    int ret = 0;
        while (ret < 3)
        {
            get_next_line(fd, &line);
            printf("%s\n", line);
            free(line);
            ret++;
        }

}

переменная строкиполучить назначение в функции get_next_line с функцией

strdup("");

, вот функция get_next_line

int get_next_line(int fd, char **line)
{
    char *buff;
    int bwr;
    char *ptr;
    int bol;
    static char *rem;


    bol = 1; 
    buff = (char *)malloc(sizeof(char) * (BUFFER_SIZE + 1));
    if(rem)
    {
        *line = ft_strdup(rem);
        printf("---1ST---%s\n", rem);
        free(rem);
        printf("---2ND---%s\n", rem);
    }
    else
        *line = ft_strdup("");
    while (bol && (bwr = read(fd, buff, BUFFER_SIZE)))
    {
        buff[bwr] = '\0';
        if ((ptr = ft_strchr(buff, '\n')))
        {
            rem = ft_strdup(ptr + 1);
            *ptr = '\0'; 
            bol = 0;
        }
        *line = ft_strjoin(*line ,buff);
    }
        return(0);
}

, поэтому я не знаю, почему она не освободит строку

PS: я использую lldb для проверки блоков памяти, спасибо.

1 Ответ

2 голосов
/ 05 ноября 2019

Я только собираюсь устранить утечки в вашей программе: Первая в этой строке:

*line = ft_strjoin(*line ,buff);

Что происходит, так как возвращаемое значение вашего ft_strjoin - это *line, старый адрес памяти, на который *line использовался для указания, теряется без освобождения и теперь *line указывает на другой адрес памяти (тот, который содержит *line + buff).

У вас есть два способа исправить эту проблему:

Первый - сделать что-то вроде этого:

char *to_free = *line;
*line = ft_strjoin(*line, buff);
free(to_free);

Это сделает to_free точкой одинаковойадрес памяти, на который указывает *line до того, как будет изменен вызовом на ft_strjoin. Другой способ (на мой взгляд, лучший) - реализовать ft_strjoin, который принимает трехмерный аргумент, например int n, если n = 1 вы освобождаете первый аргумент ft_strjoin, если n = 2, вы освобождаете2-й аргумент, если n = 3 вы освободите оба (будьте осторожны с тем, где вы освобождаете их внутри своей функции).

if (rem)

может вернуть true, даже если вы освободите его, потому что вы не сделалипотом делать rem = NULL явно (Вы также звоните printf, чтобы напечатать rem после вашего бесплатного rem.

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

...