gpt4 book ai didi

python - 在 Python C 扩展中,我应该将 Py_INCREF 和 Py_DECREF 放在这个 block 的什么位置?

转载 作者:太空狗 更新时间:2023-10-29 21:35:28 28 4
gpt4 key购买 nike

每当我调用我的函数时,每次调用都会增加大约 +10M 的内存使用量,所以我认为这里存在一些内存泄漏。

....
PyObject *pair = PyTuple_New(2), *item = PyList_New(0);

PyTuple_SetItem(pair, 0, PyInt_FromLong(v[j]));

if(v[j] != DISTANCE_MAX && (p[j] || d[0][j])){
jp=j;
while(jp!=istart) {
PyList_Append(item, PyInt_FromLong(jp));
jp=p[jp];
}

PyList_Append(item, PyInt_FromLong(jp));

PyList_Reverse(item);
}

PyTuple_SetItem(pair, 1, item);

return pair;
....

当我读到document , 一些调用如

void
bug(PyObject *list)
{
PyObject *item = PyList_GetItem(list, 0);

PyList_SetItem(list, 1, PyInt_FromLong(0L));
PyObject_Print(item, stdout, 0); /* BUG! */
}

需要像这样放引用计数

void
no_bug(PyObject *list)
{
PyObject *item = PyList_GetItem(list, 0);

Py_INCREF(item);
PyList_SetItem(list, 1, PyInt_FromLong(0L));
PyObject_Print(item, stdout, 0);
Py_DECREF(item);
}

那么,我应该将 Py_INCREF 和 Py_DECREF 放在函数的什么位置?

最佳答案

您使用 PyInt_FromLong() 创建并添加到列表中的对象应保存在局部变量中。

原因是 ownership rules : PyInt_FromLong() 生成您拥有的引用。在对 PyTuple_SetItem() 的调用中,你再次失去了这个所有权,因为 PyTuple_SetItem() 从你这里“窃取”了它,所以你不必关心。但是 PyList_Append() 不会这样做,它会增加引用计数。为了正确地对对象进行 GC,您必须通过 DECREF'ing 释放您的所有权。

因此,您执行以下操作而不是 PyList_Append(item, PyInt_FromLong(jp)):

PyObject * jpo = PyInt_FromLong(jp);
// do some error checking here
PyList_Append(item, jpo);
Py_DECREF(jpo);

这将使程序做正确的事情。

关于python - 在 Python C 扩展中,我应该将 Py_INCREF 和 Py_DECREF 放在这个 block 的什么位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6977161/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com