Что происходит с выделенными Дарвином буферами getline?
Предположим, я вызываю getline в swift с чем-то вроде этого:
import Darwin
let byLine = { (file : UnsafeMutablePointer<FILE>) in
anyGenerator({ () -> String? in
var input = UnsafeMutablePointer<Int8>()
var lim = 0
return getline(&input, &lim, file) > 0 ? String.fromCString(input) : nil
})
}
Обратите внимание на эту конкретную документацию для ssize_t getline(char **lineptr, size_t *n, FILE *stream);
:
Если *lineptr установлен в NULL, а * n установлен в 0 перед вызовом, тогда getline() выделит буфер для хранения строки. Этот буфер должен быть освобожден пользовательской программой даже в случае сбоя getline().
Теперь предположим, что у меня есть:
let fd = fopen("a_billion_lines_of_text.txt", "r")
for line in byLine(fd) {
...
}
Что происходит с миллиардом строк текста как for
цикл читает этот файл построчно?
Этот код работает для чтения файла построчно, но что происходит с каждым строковым буфером, выделенным getline
? Свифт освобождает или это утечка памяти?
1 ответ
Буферы просочились. Вам нужно освободить память после звонка getline
, Вот как вы можете это сделать.
let byLine = { (file : UnsafeMutablePointer<FILE>) in
anyGenerator({ () -> String? in
var input = UnsafeMutablePointer<Int8>()
var lim = 0
let numChars = getline(&input, &lim, file)
defer {
free(input)
}
return numChars > 0 ? String.fromCString(input) : nil
})
}