指针和;存储临时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
ed
malloc
。由于这个原因,Cython假设
malloc
是一个Python函数,返回一个您想要转换为
char*
的Python对象。在文件的顶部,添加

from libc.stdlib cimport malloc, free
它会起作用的。或者像@rll一样使用
PyMem\u Malloc
(cimporting it),这样也可以很好地工作