Посмотрите на выражение getline(&line, &len, data)
и прочтите справочную страницу:
Если перед вызовом *line установлено значение NULL, а *len установлено значение 0, то getline() выделит буфер для хранения строки. Этот буфер должен быть освобожден пользовательской программой, даже если getline() не удалось.
Это должно быть так, когда вы впервые проходите цикл (хотя мы не можем видеть, где объявлено len
, давайте просто предположим, что ваш реальный код делает это правильно)
Альтернативно, перед вызовом getline(), *line может содержать указатель на выделенный malloc(3) буфер размером *len байт. Если буфер недостаточно велик для размещения строки, getline() изменяет его размер с помощью realloc(3), обновляя *line и *len по мере необходимости.
Итак, если line != NULL
, он должен указывать на буфер, выделенный malloc
размером len
. Буфер, выделенный вашим первым вызовом getline
(как указано выше), удовлетворяет этому.
Обратите внимание, что line
недостаточно указывать куда-то в этот буфер, это должно быть начало.
Теперь посмотрите на выражение strsep(&line,"|")
и прочтите справочную страницу для < em>что:
... Этот токен завершается перезаписью разделителя нулевым байтом ('\0'), а * строка обновляется, чтобы указывать на токен
Итак, первый аргумент (line
) изменен, так что вы можете снова вызвать strsep
с тем же первым аргументом и получить следующий токен. Это означает, что line
больше не является допустимым аргументом для getline
, потому что это не начало буфера malloc
(и длина len
теперь также неверна).
На практике либо
getline
попытается прочитать len
байт в буфер, который вы ему дали, но поскольку вы увеличили line
на длину первого токена, он спишет конец выделенного вами блока. Это может просто повредить кучу, а не сразу умереть
getline
попытается перераспределить буфер, который вы ему дали, но поскольку это недопустимый выделенный блок, вы снова получите повреждение кучи.
Пока мы здесь, вы также не проверяете, что p
не равно NULL, но основная проблема заключается в повреждении line
.
О, и если вы считаете, что проблема связана с распределением, попробуйте использовать valgrind
— обычно он находит момент, когда что-то идет не так.
person
Useless
schedule
28.12.2017
strsep
изменяет свой первый аргумент, так что вы теряете начало буфераgetline
, выделенного для вас первым. Не делайте этого, используйте отдельный временный файл, если вы должны использоватьstrsep
. И проверьте, чтоp
не NULL. А где заявленоlen
? Это ноль перед вызовомgetline
? - person Useless   schedule 28.12.2017