【问题标题】:Python: ctypes and garbage collectionPython:ctypes 和垃圾收集
【发布时间】:2015-02-27 08:11:51
【问题描述】:

我有以下代码 sn-ps 代码说明了动态分配的矩阵(二维数组)

C

int** create_matrix(int r, int c)
{
    int i, j, count;

    int **arr = (int **)malloc(r * sizeof(int *));
    for (i=0; i<r; i++)
        arr[i] = (int *)malloc(c * sizeof(int));


    count = 0;
    for (i = 0; i <  r; i++)
       for (j = 0; j < c; j++)
          arr[i][j] = ++count;  

    return arr;
}

Python(调用 C 函数)

r = 3
c = 3
p_int = POINTER(POINTER(c_int))
testlib.create_matrix.restype = POINTER(POINTER(c_int))
p_int = testlib.create_matrix(r, c) #does p_int and inner array deallocated automatically in python?

我的问题是:

  1. python/ctypes 是否处理 C 分配的内存的取消分配?
  2. 如果我们要求它手动取消分配,那该怎么办?打电话免费还是别的?
    • 任何阐明相同内容的博客或帖子都会很棒

【问题讨论】:

  • 为什么会有p_int = POINTER(POINTER(c_int))这一行?这并没有做任何有用的事情。
  • ctypes 不会free 指针数组,也不会是行。首先,它不拥有内存,所以这将是一个糟糕的主意。再加上它不知道p_int指向一个指针数组,也不知道数组的长度,那么它怎么知道它需要免费调用r+1次呢?

标签: python c ctypes


【解决方案1】:

python/ctypes 是否处理 C 分配的内存的释放?

如果你的代码调用malloc();你有责任调用调用free()的代码。

如果我们要求它手动取消分配,那怎么办?打电话免费还是别的? 任何阐明相同内容的博客或帖子都会很棒

C 代码应提供互补的free_matrix() 函数,该函数应由调用create_matrix() 的代码调用。 free_matrix()example的实现有很多。

您可以将create_matrix()free_matrix() 包装到一个对象中并在其__del__() 方法中调用free_matrix()。和/或如果您想要更确定的方法(调用__del__() 的时间或是否调用它取决于实现);你可以创建一个上下文管理器:

from contextlib import contexmanager

@contextmanager
def matrix():
    m = Matrix() # calls create_matrix() internally
    try:
        yield m # Matrix() may protect against out-of-bound error
    finally:
        m.clear() # call free_matrix()

例子:

with matrix() as m:
   print(m[0][1])

【讨论】:

  • +1,但如果可能的话,库应该让客户端分配聚合数据。在这种情况下,OP 可以使用 ctypes 数组,例如 p_int = (c_int * c * r)(),它是解释器的引用计数。
  • @eryksun:是的。接受预先分配的缓冲区是一个不错的选择。注意:为了清楚起见,请使用 ((c_int * c) * r),以避免与 (c_int * (c * r)) 混淆。
  • 我通常避免使用括号来阐明运算顺序和二元运算,除非它是一个特别复杂的表达式。我以为c_int * c * r的评价不言而喻。
  • @eryksun:鉴于* 在大多数情况下是关联运算符,与本例不同;即使您自己始终记得正确的解释是什么,括号也是必要的。
猜你喜欢
  • 2012-03-21
  • 2013-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-28
相关资源
最近更新 更多