【问题标题】:Python C API Read a list of list, allocate memory and global VariablesPython C API 读取列表,分配内存和全局变量
【发布时间】:2014-05-03 09:19:13
【问题描述】:

我正在编写一个模块以优化操作,但我有几个问题。

第一

我需要从 python 读取一个数组(列表列表)到 C,我是这样做的:

long i_k;
for (int k = 0; k < n; k++) {
  PyObject *first = PyList_GetItem(streamMatrixObj, k);
  for (int i = 0; i < n; i++) {
    PyObject *second = PyList_GetItem(first, i);
    i_k = PyLong_AsLong(second);
    f[k][i] = i_k;
  }
} 

矩阵总是n x n。有没有更好的方法来读取列表列表并将其存储到 C 数组中?

第二

我正在为 C 数组分配内存,如下所示:

void **createMatrix(uint rows, uint cols) {

  long **matrix;

  const size_t row_pointers_bytes = rows * sizeof(*matrix);
  const size_t row_elements_bytes = cols * sizeof(**matrix);
  matrix = PyObject_Malloc(row_pointers_bytes + rows * row_elements_bytes);

  if (!matrix) {
    PyErr_NoMemory();
    return NULL;
  }

  size_t i = 0;
  long *data = matrix + rows;
  for (i = 0; i < rows; i++)
    matrix[i] = data + i * cols;

  return matrix;
}

我应该使用PyMem_Malloc还是PyObject_Malloc?,我在这个问题中看到了解释

Is there any reason to use malloc over PyMem_Malloc?

但还是不知道该调用什么函数。

第三

这个模块的方法会被多次调用,所以我想把C数组保存在内存中,以免每次都重新创建数组。例如,在 python 中,我会调用方法myModule.deltaC(1,2,[1,2,3]),该调用将对矩阵进行一些操作。

我可以在使用deltaC 函数之前初始化数组,例如myModule.initMatrix([[1,2,3],[1,2,3], [1,2,3]]),并将其保存在内存中直到程序完成?那么C数组需要成为模块中的全局变量吗?

更新

我尝试使用 module.initMatrix 在全局变量中初始化 C 数组,但是当调用 module.delta 时,我在访问 C 数组时遇到了 SegFault,所以我想这是不可能的,或者我错过了东西。

第四个

有没有办法检测 python 程序何时完成以调用PyObject_free(array) 以释放为 C 数组分配的内存?

【问题讨论】:

    标签: python c arrays memory-management python-c-api


    【解决方案1】:

    首先:这就是它应该如何完成的。

    第二:据我了解,您应该在这里PyMem_Malloc/PyMem_Free。 PyObject_Malloc/PyObject_Free 用于分配 Python 对象,并针对许多较小的对象进行了优化。但是,除非您分配大量内存或进行大量分配,否则这无关紧要。

    第三和第四:您可以使用Capsules API 来存储您的 C 结构并将它们传递给 API 函数。您可以让初始化函数(initMatrix)返回一个包含矩阵的胶囊,并将这个胶囊传递给其他函数(例如 deltaC),而不是存储全局矩阵。当矩阵不再被引用时,它会被自动销毁。

    如果您不打算存储除矩阵之外的任何内容,则可能的替代方法是使用numpy 数组。这些数组可以通过 C 中的 numpy C API 作为矩阵直接访问。这将使您无需调用 Python C API 函数来检索矩阵的每个元素、自行分配内存或在销毁时释放内存。

    【讨论】:

    • 感谢您的回复。在第二个我想知道这是否是分配内存的正确方法。我应该使用PyObject_Malloc 还是PyMem_Malloc?我要看看 Capsules 看看我能不能让它发挥作用。
    猜你喜欢
    • 1970-01-01
    • 2012-08-12
    • 1970-01-01
    • 1970-01-01
    • 2013-07-06
    • 1970-01-01
    • 2021-12-09
    • 2023-03-19
    • 2021-04-24
    相关资源
    最近更新 更多