0

我想知道如何应对以下问题。在我的 C++ 类中,我有一个辅助 PyObject 指针。

class Foo
{
     public:
     // Should I new the dictionary here in constructor?
     Foo()
     {

     }
     // Must decrease the reference count or explicitly delete the dictionary?
     ~Foo()
     {
         Py_DECREF(myDictionary);
     }

     void sync()
     {
          myDictionary = PyDict_New();
          for (int i=0; i<myInternalData.size(); i++)
          {
                  PyObject *key =  PyInt_FromLong(i);
                  PyObject *val = PyInt_FromLong(myInternalData.at(i));
                  PyDict_SetItem(dict,key,val);
                  Py_DecRef(key);
                  Py_DecRef(val);
          }
     }

     private:
     PyObject *myDictionary;
     std::vector<int> myInternalData;
}

在我的 C++ 代码中,myInternalData结构偶尔会更新或调整大小,我想知道如何处理我的 python 字典的正确内存分配。

我不知道如何释放与其关联的内存,或者如何正确地保持它与我的内部同步,std::vector而不会破坏堆或引发内存泄漏。

对 Python C API 有帮助吗?我应该释放 PyDictPyObject_Del然后再重新分配它吗?有人建议另一种方法?

4

1 回答 1

1

我不清楚为什么要在 Python 中使用字典,当您使用从 0 开始的连续整数集进行索引时。但是:在使用它之前,您必须PyDict_New先创建字典。之后,当你重新同步时,你应该在开始之前清除字典,使用 PyDict_Clear,而不是重新分配一个新的.. 没有其他必要了。(如果您重新分配一个新的,就像您在代码中所做的那样,您应该首先减少旧的引用计数。但是 Python 端的任何引用旧的代码将继续引用旧的;PyDict_Clear是可能是更好的解决方案。)

此外,您应该注意涉及临时 Python 对象的位置。目前,没有其他必要,因为您只在循环中使用 Python(以及 C)函数,它们不会触发 C++ 异常。稍微改变一下代码,这可能不再是这种情况。作为一般规则,我发现您应该将 包装PyObject*在析构函数调用的类中Py_DecRef,而不是显式调用它,并且可能由于异常而错过调用。

于 2013-01-07T14:17:58.677 回答