我在pyx文件中的cython中有以下代码,它将wchar_t *转换为python字符串(unicode)
//以下所有代码均为python 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上对此进行了测试,观察结果是内存(如任务管理器中所示)不断增加,因此我怀疑此处可能存在内存泄漏。
这是令人惊讶的,因为:
知道我哪里错了吗?有没有更好的方法将Py Char实现为python unicode对象?
答案 0 :(得分: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)
根据文档添加'object'作为返回类型不会增加任何引用计数,因此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