2015-12-17 87 views
3

假設我稱之爲迅速getline像這樣的東西:Darwin分配了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);這個特定的文檔:

如果* lineptr設置爲NULL和* N呼叫之前被設置爲0,然後 getline()將分配一個緩衝區來存儲該行。即使getline()失敗,該緩衝區 也應該由用戶程序釋放。

現在假設我有:

let fd = fopen("a_billion_lines_of_text.txt", "r") 
for line in byLine(fd) { 
    ... 
}  

到十億行文本會發生什麼作爲for循環一行讀取文件中的行?

這段代碼確實可以逐行讀取文件,但是由getline分配的每個行緩衝區會發生什麼?快速釋放它還是內存泄漏?

+1

鑑於您沒有釋放文檔明確說明您需要釋放的內容,這是內存泄漏。 – Ryan

+0

你如何快速解脫?我知道如何在C中做到這一點,但不是間接地迅速。 – dawg

回答

4

緩衝區泄漏。撥打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 
    }) 
} 
+0

'defer'會在關閉範圍執行並在使用前釋放'input'? – dawg

+0

'input'在使用之前不會被釋放。 'defer'塊中的代碼將在返回之前執行,但在閉包中的所有其他代碼完成執行之後。這意味着免費將發生在numChars> 0之後? String.fromCString(input):nil)'已被評估。 –

+0

然後函數(閉包)在釋放之前將'input'的內容複製到不同的緩衝區中?在C中,在緩衝區中調用'free'然後從函數返回是一個常見錯誤... – dawg