Python C Api和正确处理c++类中的内存

Python C Api and correct handling of memory in C++ classes

本文关键字:内存 c++ 正确处理 Api Python      更新时间:2023-10-16

我想知道如何处理以下问题。在我的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的一些帮助?我应该用PyObject_Del重新分配PyDict,然后再重新分配吗?有人建议另一种方法吗?

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

另外,您应该注意临时Python对象有关。目前,不需要别的了,因为在循环中只使用Python(因此,C)函数,并且它们不能触发c++异常。无论如何都要更改代码稍微有点,但情况可能不再是这样。一般来说,我发现你应该把PyObject*包装在一个类中析构函数调用Py_DecRef,而不是显式地调用它,并且可能由于异常而错过呼叫。