使用 Python 的 C++ 扩展了解内存泄漏

问题描述 投票:0回答:1

我一直在努力理解我在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 解释器传递而不是在函数中分配时,内存泄漏按预期消失了。

python c++ memory-management python-extensions
1个回答
0
投票
不需要

Py_XINCREF(x_obj)
,因为
Py_BuildValue("O", x_obj)
会为您增加引用计数。换句话说,您不小心将引用计数增加了太多 1

© www.soinside.com 2019 - 2024. All rights reserved.