将宽字符转换为python字符串时潜在的内存泄漏

我在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上对此进行了测试,发现内存(在任务管理器中看到)不断增加,因此我怀疑这里可能存在内存泄漏.

这是令人惊讶的,因为:

>根据我的理解,API PyUnicode_FromWideChar()复制了
提供的缓冲区.
>每次为变量“ u”分配一个不同的值,即前一个值
应该释放
>由于源缓冲区(‘buf’)保持原样,并且仅在循环之后才释放
结束时,我原本以为内存在某个特定点之后根本不应该增加

知道我哪里出错了吗?有没有更好的方法来实现Wide Char到python unicode对象?

解决方法:

解决了!!
解:

(注意:该解决方案引用的是我本来不在代码中的一部分代码.发布该解决方案的关键在于我没有任何线索.抱歉,那些想出解决此问题的人…)

在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 *,因此创建了一个附加引用,但没有明确取消引用.解决方案是更改签名中的返回类型,例如:

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
上一篇:python-Cython的C API声明失败


下一篇:加快Python程序速度的11个技巧