首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Cython -返回类型的任意长度MemoryView

Cython -返回类型的任意长度MemoryView
EN

Stack Overflow用户
提问于 2016-11-20 21:13:25
回答 1查看 880关注 0票数 0

我编写了一个Cython函数,它以数字的list/类型化内存视图作为参数,并返回相同长度的类型化内存视图:

代码语言:javascript
运行
复制
def test(list_data):
    cdef unsigned int n = len(list_data)
    cdef unsigned int i = 0
    cdef double *results_arr = <double*>malloc(n* sizeof(double) )
    cdef double[:] results = <double[:n]>results_arr
    for i in range(n):
        results[i] = 220 - list_data[i]
    return results

在对它进行了几千次测试之后,我开始得到一个Segmentation fault (core dumped)错误。我意识到这是内存管理问题,但我找不到如何管理函数返回的类型化内存视图的内存的示例。我找到的唯一有用的信息是关于内存分配的,它建议将result_arr的生存期绑定到python对象,并使用__dealloc__方法来释放内存。

是否有一种不需要创建python类来释放内存的内存视图垃圾收集方法?

编辑:我试过了,它似乎以正确的方式释放了内存。

代码语言:javascript
运行
复制
def test(list_data):
    cdef unsigned int n = len(list_data)
    cdef unsigned int i = 0
    cdef double *arr = <double*>malloc(n* sizeof(double) )
    if not arr:
        raise MemoryError()
    cdef double[:] results = <double[:n]>arr
    for i in range(n):
        results[i] = 220 - list_data[i]
    free(arr)
    return results

为什么这是工作的,是否有更好的方法来管理内存?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-11-21 11:15:50

类型化内存视图顾名思义,是内存缓冲区的视图。它不拥有该内存,但提供了一种访问它的有效方法。您所指的cython文档的部分是将分配给python垃圾收集器的底层堆分配给垃圾收集器的一种方法。如果您想像在这里一样使用c内存分配,那么您也必须对它负责。这是因为您现在在c级别上工作,而c不免费为您做任何事情。您的函数可以查看分配的内存,但会丢弃引用它的指针。现在,这种记忆无所事事,没有任何责任来释放它。

如果您不想进入c的世界,我建议您将数据读入python中的numpy数组,然后将这个数组传递给cython函数。Python和numpy非常适合这类事情。

但是,如果您想使用malloc,另一种方法可能是将其封装为扩展类型。

代码语言:javascript
运行
复制
cdef class mymemory:
    cdef:
        double *arr
        double[::1] results

    def __cinit__(self, int n):
        self.arr = <double*>malloc(n*sizeof(double))

    def __init__(self, int n):
        self.results = <double[:n]> arr

        """
        Some code for filling in the results.
        """

    def __dealloc(self):
        if self.arr != NULL:
            free(self.arr)

现在,当mymemory被垃圾收集时,底层的c数组就被释放了。这是一个选择,因为你要求它,但我仍然建议numpy超过这一点。

在第二个函数中,您似乎分配了内存,为它创建一个视图,然后再释放它。现在,这个内存视图正在查看的内存不再存在。所以你是正确的,内存被正确释放。但是现在记忆不再对你有任何用处了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40709448

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档