Cython从函数返回maloced指针

2024-04-27 11:41:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我对Cython相当陌生,所以这可能是相当微不足道的,但我在任何地方都找不到答案。在

我已经定义了一个结构类型,我想写一个函数来正确初始化所有字段并返回指向新结构的指针。在

from cpython.mem import PyMem_Malloc


ctypedef struct cell_t:
    DTYPE_t[2] min_bounds
    DTYPE_t[2] max_bounds
    DTYPE_t size

    bint is_leaf
    cell_t * children[4]

    DTYPE_t[2] center_of_mass
    UINT32_t count


cdef cell_t * make_cell(DTYPE_t[2] min_bounds, DTYPE_t[2] max_bounds):
    cdef cell_t * cell = <cell_t *>PyMem_Malloc(sizeof(cell_t)) # <- Fails here
    if not cell:
        MemoryError()

    cell.min_bounds[:] = min_bounds
    cell.max_bounds[:] = max_bounds
    cell.size = min_bounds[0] - max_bounds[0]
    cell.is_leaf = True
    cell.center_of_mass[:] = [0, 0]
    cell.count = 0

    return cell

但是,当我试图编译此文件时,在编译过程中出现以下两个错误:

^{pr2}$

现在,我已经查看了所有内容,从我所能收集到的信息来看,cell实际上存储在一个临时变量中,该变量在函数末尾被释放。在

任何帮助都将不胜感激。在


Tags: of函数sizeiscellmin结构max
1条回答
网友
1楼 · 发布于 2024-04-27 11:41:07
cell.min_bounds = min_bounds

这并不像你想象的那样(尽管我不能百分之百确定它能做什么)。您需要逐元素复制数组:

^{pr2}$

max_bounds也一样。在

我怀疑给你的错误信息是:

cell.center_of_mass = [0, 0]

这试图将Python列表分配给一个C数组(记住数组和指针在C中是可以互换的),这没有多大意义。再说一遍,你会的

cell.center_of_mass[0] = 0
cell.center_of_mass[1] = 0

所有这些在很大程度上与C的行为一致,即没有操作符将整个数组相互复制,您需要逐个元素地复制。在


编辑:

但这不是你现在的问题。您没有声明PyMem_Malloc,所以假设它是一个Python函数。你应该这么做

from cpython.mem cimport PyMem_Malloc

确保它是cimported,而不是{}ed


编辑2:

以下内容对我来说很好:

from cpython.mem cimport PyMem_Malloc

ctypedef double DTYPE_t

ctypedef struct cell_t:
    DTYPE_t[2] min_bounds
    DTYPE_t[2] max_bounds


cdef cell_t * make_cell(DTYPE_t[2] min_bounds, DTYPE_t[2] max_bounds) except NULL:
    cdef cell_t * cell = <cell_t *>PyMem_Malloc(sizeof(cell_t))
    if not cell:
        raise MemoryError()
    return cell

我减少了cell_t一点(只是为了避免声明UINT32_t)。我还给了cdef函数一个except NULL,允许它在需要时发出错误信号,并在MemoryError()之前添加了一个raise。我不认为这些变化与你的错误有直接关系。在

相关问题 更多 >