2014-12-07 81 views
3

我已經在PYX文件,用Cython下面的代碼,其爲wchar_t *轉換爲Python字符串(Unicode)的潛在內存泄漏

//下面的所有代碼是蟒2.7.4

cdef wc_to_pystr(wchar_t *buf): 
    if buf == NULL: 
     return None 
    cdef size_t buflen 
    buflen = wcslen(buf) 
    cdef PyObject *p = PyUnicode_FromWideChar(buf, buflen) 
    return <unicode>p 

我叫在這樣的循環這個功能:

cdef wchar_t* buf = <wchar_t*>calloc(100, sizeof(wchar_t)) 
# ... copy some wide string to buf 

for n in range(30000): 
    u = wc_to_pystr(buf) #<== behaves as if its a memory leak 

free(buf) 

我測試了在Windows和觀察是內存(如被看見在任務管理器)不斷增加和h因爲我懷疑這裏可能會有內存泄漏。

  1. 按我的理解API PyUnicode_FromWideChar()複製 提供的緩衝區:

    這是因爲是令人驚訝的。

  2. 每個時間變量「U」被分配一個不同的值,先前的值 應當釋放出的
  3. 由於源緩衝器(「BUF」)仍保持原樣,只在循環之後被釋放 端,我期待內存不應該增加一定的點後

任何想法,我哪裏錯了?有沒有更好的方法來實現寬字符到python unicode對象?

+0

你可以嘗試在for循環中添加一個'del u'並檢查內存是否繼續增加? – gg349 2014-12-07 17:49:14

+0

@GiulioGhirardo,我試着按照你的說法,仍然記憶力不斷增加。在這一點上,我不確定它是真正的內存泄漏還是python GC有點懶惰收集垃圾 – user2248790 2014-12-08 02:41:23

回答

3

解決了! 解決方案:

(注:該解決方案是指一段我的代碼是不是在這個問題我原本同時發佈,這將持有解決這個關鍵不知道對不起那些誰給它一個念頭來解決......)

地用Cython PYX文件,我已宣佈了Python API,如:

PyObject* PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size) 

我簽出的文檔在https://github.com/cython/cython/blob/master/Cython/Includes/cpython/init.pxd

我已經聲明瞭返回類型爲PyObject *,因此創建了一個額外的ref,我並沒有明確地解釋。的解決方案是改變返回類型在簽名等:

object PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size) 

作爲每文檔添加「對象」作爲返回類型不增加任何引用計數,從而在for循環內存被釋放,正確。修改後的'wc_to_pystr'看起來像這樣:

cdef wc_to_pystr(wchar_t *buf): 
    if buf == NULL: 
     return None 
    cdef size_t buflen 
    buflen = wcslen(buf) 
    p = PyUnicode_FromWideChar(buf, buflen) 
    return p