将char *分配给python对象时会发生什么?

时间:2015-04-14 11:40:45

标签: python cython

我有以下代码。

cdef char * buf
buf = <LPSTR>PyMem_Malloc(sizeof(char) * buf_size)
# Some work on buff.
py_byte_string = buf
PyMem_Free(buf)
return py_byte_string

看起来buf已被释放,py_byte_string被发送回调用者。这段代码好吗?我没有任何功能问题。但是返回一个释放的指针并不舒服。

1 个答案:

答案 0 :(得分:1)

你是正确的怀疑...使用cython -a <filename>查看它生成的代码(或跳过&#34; -a&#34;并查看原始c文件)。

我不会把它全部粘贴在这里,因为它有相当多的一部分,但靠近函数顶部的地方是:

char *__pyx_v_buf;
char *__pyx_v_py_byte_string;

(即假设py_byte_string是一个char指针)

py_byte_string = buf已翻译为

__pyx_v_py_byte_string = __pyx_v_buf;

然后转换发生在return语句(return py_byte_string):

__Pyx_XDECREF(__pyx_r);
__pyx_t_2 = __Pyx_PyBytes_FromString(__pyx_v_py_byte_string); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_2);
__pyx_r = __pyx_t_2;
__pyx_t_2 = 0;
goto __pyx_L0;

因为这是在你释放了内存之后它可以运行的纯粹好运,你可以通过在免费和返回之间分配和使用更多内存来打破它。

要强制它安全地工作,您需要做的就是添加

cdef object py_byte_string # tell Cython this should be a plain Python object

然后转换发生在分配线上,它应该在那里进行。

供参考__Pyx_PyBytes_FromString看起来是PyBytes_FromString的一个宏,它被指定为复制它传递的字符串,因此所有内容都应该是安全的。