指针和;存储临时Python引用的不安全C派生;
我正在编写代码,将一个(可能)非常大的整数值存储到一个由指针引用的指针和;存储临时Python引用的不安全C派生;,python,c,pointers,cython,python-extensions,Python,C,Pointers,Cython,Python Extensions,我正在编写代码,将一个(可能)非常大的整数值存储到一个由指针引用的字符数组中。我的代码如下所示: cdef class Variable: cdef unsigned int Length cdef char * Array def __cinit__(self, var, length): self.Length = length self.Array = <char *>malloc(self.Length * size
字符数组中。我的代码如下所示:
cdef class Variable:
cdef unsigned int Length
cdef char * Array
def __cinit__(self, var, length):
self.Length = length
self.Array = <char *>malloc(self.Length * sizeof(char)) # Error
for i in range(self.Length):
self.Array[i] = <char>(var >> (8 * i))
def __dealloc__(self):
self.Array = NULL
cdef类变量:
无符号整数长度
cdef char*数组
定义(自身、变量、长度):
self.Length=长度
self.Array=malloc(self.Length*sizeof(char))#错误
对于范围内的i(自身长度):
self.Array[i]=(var>>(8*i))
def uu dealoc uu(自我):
self.Array=NULL
当我试图编译代码时,在注释行中出现了错误,“存储临时Python引用的不安全C派生”。我的问题是:我在C中导出并存储哪个临时Python引用,以及如何修复它?问题是,在分配给self.array
之前,正在创建一个临时变量来保存数组,一旦该方法退出,它将无效
请注意,报告建议:
用于在Python堆上分配内存的C-API函数通常优于上面的低级C函数,因为它们提供的内存实际上是在Python的内部内存管理系统中占用的。它们还对较小的内存块进行了特殊优化,从而避免了昂贵的操作系统调用,从而加快了内存块的分配
因此,您可以编写如下内容,这似乎可以按预期处理此用例:
from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free
cdef class Variable:
cdef unsigned int Length
cdef char * Array
def __cinit__(self, var,size_t length):
self.Length = length
self.Array = <char *>PyMem_Malloc(length * sizeof(char))
#as in docs, a good practice
if not self.Array:
raise MemoryError()
for i in range(self.Length):
self.Array[i] = <char>(var >> (8 * i))
def __dealloc__(self):
PyMem_Free(self.Array)
来自cpython.mem cimport PyMem_Malloc、PyMem_Realloc、PyMem_Free
cdef类变量:
无符号整数长度
cdef char*数组
定义(自身、变量、大小和长度):
self.Length=长度
self.Array=PyMem_Malloc(长度*sizeof(字符))
#正如在文档中一样,这是一个好的实践
如果不是self.Array:
提高内存错误()
对于范围内的i(自身长度):
self.Array[i]=(var>>(8*i))
def uu dealoc uu(自我):
PyMem_Free(self.Array)
@rll的答案在清理代码和“正确处理一切”方面做得相当好(最重要的是问题中\uuuuuuu dealoc\uuuuu
缺少的内存释放!)
导致错误的实际问题是您没有cimport
edmalloc
。由于这个原因,Cython假设malloc
是一个Python函数,返回一个您想要转换为char*
的Python对象。在文件的顶部,添加
from libc.stdlib cimport malloc, free
它会起作用的。或者像@rll一样使用PyMem\u Malloc
(cimporting it),这样也可以很好地工作