Что происходит с выделенными Дарвином буферами 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
    })
}
Другие вопросы по тегам