@Midzakikayo

Почему происходит ошибка сегментации и как её избежать?

Всем добра и тепла! Делаю учебное задание. Нужно реализовать функционал Get next line и возможность принять параметр буффера. В голову пришла простоя идея, читать данные из файла, до тех пор пока не встретим перенос на новую строку или же не встретим конец строки, мы будем читать длинну буффера, забивая в строку. Строку формируем заранее с помощью malloc по длинне буффера + 1 символ на конец строки. Проблемма возникла в том что при чтение порядка цифр при достижении конца строки я натыкаюсь на Segmentation fault.
К примеру есть строка 12345. я передаю 3 в буффер, и делаю два вызова функции в итоге получа форматирование строки
123
Segmentation fault.
НЕ могу понять почему. так...( Подскажите пожалуйста.

char *get_next_line(int fd)
{
    char *line;
    int read_byte;
    char rwrite;
    long long int i;

    i = 0;
    line = (char *)malloc(sizeof(char) * (BUFFER_SIZE + 1));
    if (!line)
        return (NULL);
    while (i != BUFFER_SIZE)
    {
        read_byte = read(fd, &rwrite, 1);
        if (read_byte && rwrite)
        {
            if (rwrite != '\n' && rwrite != '\0')
                line[i] = rwrite;
            else 
            {
                line[i] = '\0';
                return (line);
            }
        }
        else if (read_byte <= 0)
            return (NULL);
        i++;
    }
    line[i] = '\0';
    return (line);
}
  • Вопрос задан
  • 105 просмотров
Пригласить эксперта
Ответы на вопрос 1
RiseOfDeath
@RiseOfDeath
Диванный эксперт.
Долго не мог понять что не так. (увы нет компилятора под рукой)

В общем чисто "на глаз", если я не ошибся нигде:
Если вы делаете два вызова с буфером размера 3. (а реальная длинна строки 5), то втором вызове ваша функция вернет вам NULL и вы (вероятно) нигде это не проверяете (проверьте на всякий случай что я тут не ошибся)

Поясню - если буфер длиннее файла, то вы столкнувшись с тем что больше нечего читать т.е. при прочтении 0 байтов (а у вас их именно 0 будет прочитано, если файл кончился) возвращаете NULL вместо того, чтобы вернуть то, что смогли прочитать или еще что-нибудь сделать
И, к стати, допускаете утечку - вы под line выделили память, но в случае ошибки не очищаете ее и никуда не возвращаете.

см. https://man7.org/linux/man-pages/man2/read.2.html

Ну и опустим тот момент что у вас строка будет распилена на несколько если не влезет в заданный размер буфера.

Как вариант читать строку пока не кончится, по мере исчерпания буфера вызывать realloc (например с шагом в BUFFER_SIZE). Если буфер будет чуть больше полученой строки это не трагедия (опять же, если вдруг все-таки трагедия - realloc в помощь).
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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