c ++ - to-python swig导致内存泄漏!与Py_BuildValue和SWIG_NewPointerObj相关

时间:2010-06-02 01:47:23

标签: python swig

我有以下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文档,但没有看到非常具体的描述。

请帮忙!

谢谢, 辛

1 个答案:

答案 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的引用计数:如果我在将对象传递给元组或列表时正确回想起引用被盗。