我一直在努力理解我在Python模块的这个C++函数的内存管理上做错了什么,但我在这方面没有太多经验。
每次运行这个函数,Python解释器的内存消耗都会增加。该函数应该接受两个 numpy 数组并创建具有所需输出的新 numpy 数组。
extern "C" PyObject *radec_to_xyz(PyObject *self, PyObject *args) {
// Parse the input arguments
PyArrayObject *ra_arrobj, *dec_arrobj;
if (!PyArg_ParseTuple(args, "O!O!", &PyArray_Type, &ra_arrobj, &PyArray_Type, &dec_arrobj)) {
PyErr_SetString(PyExc_TypeError, "invalid arguments, expected two numpy arrays");
return nullptr;
}
// skipping checks that would ensure:
// dtype==float64, dim==1, len()>0 and equal for inputs, data or contiguous
npy_intp size = PyArray_SIZE(ra_arrobj);
// create the output numpy array with the same size and datatype
PyObject *x_obj = PyArray_EMPTY(1, &size, NPY_FLOAT64, 0);
if (!x_obj) return nullptr;
Py_XINCREF(x_obj);
// get pointers to the arrays
double *ra_array = static_cast<double *>(PyArray_DATA(ra_arrobj));
double *dec_array = static_cast<double *>(PyArray_DATA(dec_arrobj));
double *x_array = static_cast<double *>(PyArray_DATA(reinterpret_cast<PyArrayObject*>(x_obj)));
// compute the new coordinates
for (npy_intp i = 0; i < size; ++i) {
double cos_ra = cos(ra_array[i]);
double cos_dec = cos(dec_array[i]);
// compute final coordinates
x_array[i] = cos_ra * cos_dec;
}
// return the arrays holding the new coordinates
return Py_BuildValue("O", x_obj);
}
我怀疑我的引用计数错误,因此返回的 numpy 数组不会被垃圾收集。我尝试更改引用计数,但这没有帮助。
当我将 X 数组作为附加参数从 python 解释器传递而不是在函数中分配时,内存泄漏按预期消失了。
Py_XINCREF(x_obj)
,因为 Py_BuildValue("O", x_obj)
会为您增加引用计数。换句话说,您不小心将引用计数增加了太多 1