我有以下Swig代码导致内存泄漏。
PyObject* FindBestMatch(const Bar& fp) {
Foo* ptr(new Foo());
float match;
// call a function to fill the foo pointer
return Py_BuildValue(
"(fO)",
match,
SWIG_NewPointerObj(ptr,
SWIGTYPE_p_Foo,
0 /* own */));
}
我认为ptr没有正确释放。所以我做了以下事情:
PyObject* FindBestMatch(const Bar& fp) {
Foo* ptr(new Foo());
float match;
// call a function to fill the foo pointer
*PyObject *o = SWIG_NewPointerObj(ptr,
SWIGTYPE_p_Foo,
1 /* own */);* <------- 1 means pass the ownership to python
PyObject *result = Py_BuildValue("(fO)", match, o);
Py_XDECREF(o);
return result;
}
但我不确定这是否会导致内存损坏。这里,Py_XDECREF(o)将减少引用计数,这可以释放对象“o”使用的内存。但是o是返回值“结果”的一部分。我想,释放“o”会导致数据损坏?
我尝试了改变。它工作正常,调用者(python代码)确实看到了预期的数据。但这可能是因为没有其他人覆盖到那个记忆区域。
那么处理上述代码的内存管理的正确方法是什么?我搜索swig文档,但没有看到非常具体的描述。
请帮忙!
谢谢, 辛
答案 0 :(得分:0)
根据SWIG为分配新对象的函数自动生成的代码,正确的方法应该是将Python Ownership标志设置为1,这意味着: python拥有此指针 <登记/>
这是有道理的:你的new Foo()
可以在哪里被解除分配? Swig包装器对象将处理它。
PyObject* FindBestMatch(const Bar& fp) {
Foo* ptr(new Foo());
float match;
// call a function to fill the foo pointer
PyObject* o = SWIG_NewPointerObj(ptr,
SWIGTYPE_p_Foo,
SWIG_BUILTIN_INIT | 0);
PyObject* result = Py_BuildValue("(fO)", match, o);
return result;
}
但是我不明白为什么你会减少对o的引用计数:如果我在将对象传递给元组或列表时正确回想起引用被盗。