Darwin 分配的 getline 缓冲区会怎样?
What happens to Darwin allocated getline buffers?
假设我在 swift 中用这样的方式调用 getline:
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);
的特定文档:
If *lineptr is set to NULL and *n is set 0 before the call, then
getline() will allocate a buffer for storing the line. This buffer
should be freed by the user program even if getline() failed.
现在假设我有:
let fd = fopen("a_billion_lines_of_text.txt", "r")
for line in byLine(fd) {
...
}
当 for
循环逐行读取该文件时,十亿行文本会发生什么情况?
此代码确实适用于逐行读取文件,但是 getline
分配的每一行缓冲区会发生什么情况? swift 释放它还是内存泄漏?
缓冲区泄漏。您需要在调用 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
})
}
假设我在 swift 中用这样的方式调用 getline:
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);
的特定文档:
If *lineptr is set to NULL and *n is set 0 before the call, then getline() will allocate a buffer for storing the line. This buffer should be freed by the user program even if getline() failed.
现在假设我有:
let fd = fopen("a_billion_lines_of_text.txt", "r")
for line in byLine(fd) {
...
}
当 for
循环逐行读取该文件时,十亿行文本会发生什么情况?
此代码确实适用于逐行读取文件,但是 getline
分配的每一行缓冲区会发生什么情况? swift 释放它还是内存泄漏?
缓冲区泄漏。您需要在调用 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
})
}