将列表作为参数发送时验证 Python 引用计数

我有一个 C++ 类,它将 Python 模块作为文件导入,并在返回接收到的数据之前连续调用它的函数:


ProgramLiveProcess::ProgramLiveProcess() {

    //Start Python to run the Program Python code

    Py_Initialize();


    //Import the Program live processing module

    program_live_processing_module = PyImport_ImportModule(MODULE_NAME);


    //Get the objects for the functions to call

    live_process = PyObject_GetAttrString(program_live_processing_module, "Program_LiveProcess");

}


//Creates Python list from intensities array

PyObject* ProgramLiveProcess::get_intensities_list(unsigned int intensities[INTENSITIES_DATA_SIZE]) {

    PyObjec* tr = PyList_New(0);

    for (int i = 0; i < INTENSITIES_DATA_SIZE; i++) {

        PyObject* ta = PyLong_FromLong(intensities[i]);

        PyList_Append(tr, ta);

    }

    return tr;

}


//TODO: Make this actually work

//Frees objects in intensities Python list and the list itself

void ProgramLiveProcess::free_intensities_list(PyObject* i_list) {

    //std::cout << std::to_string(i_list->ob_refcnt) << std::endl;

    for (int i = 0; i < INTENSITIES_DATA_SIZE; i++) {

        PyObject* ta = PyList_GET_ITEM(i_list, i);

        Py_DECREF(ta);

    }

    Py_DECREF(i_list);

}


processed_data* ProgramLiveProcess::send_to_program_live_process(unsigned int intensities[INTENSITIES_DATA_SIZE], bool use_sensor_1) {

    //Call the Program_LiveProcess function

    PyObject* intensities_py = get_intensities_list(intensities);

    PyObject* calculate_args = PyTuple_Pack(2, intensities_py, use_sensor_1 ? Py_True : Py_False); //True or false depending on if using sensor 1 or 2

    PyObject* processed_data_tuple = PyObject_CallObject(live_process, calculate_args);

    Py_DECREF(calculate_args);

    free_intensities_list(intensities_py);


    //Get the data from the function

    PyObject* s0p = PyTuple_GetItem(processed_data_tuple, 0);

    PyObject* s0t = PyTuple_GetItem(processed_data_tuple, 1);

}


虽然程序接收数据很好,但在不同条件下运行时,我在内存泄漏和崩溃方面遇到了不一致的情况。虽然我无法提供堆栈跟踪,但我想知道我在创建或取消引用 Python 对象方面是否做错了什么。通常,程序仅在我注释掉 free_intensities_list 调用时运行。


尚方宝剑之说
浏览 2628回答 1
1回答

动漫人物

在你的free_intensities_list函数中,你可能会进行双重释放。考虑使用Py_XDECREF代替。void Py_DECREF(PyObject *o) Decrement the reference count for object o. The object must not be NULL; if you aren’t sure that it isn’t NULL, use Py_XDECREF(). If the reference count reaches zero, the object’s type’s deallocation function (which must not be NULL) is invoked.
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python