2014-12-07 83 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