我有以下代码。
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被发送回调用者。这段代码好吗?我没有任何功能问题。但是返回一个释放的指针并不舒服。
答案 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
的一个宏,它被指定为复制它传递的字符串,因此所有内容都应该是安全的。