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に役立つものはありますか?PyDictの割り当てを解除してPyObject_Delから、再度再割り当てする必要がありますか?別のアプローチを提案している人はいますか?

4

1 に答える 1

1

0 から始まる連続した整数のセットでインデックスを作成するときに、Python で辞書を使用している理由は明確ではありません。ただし、使用する前にPyDict_New、辞書を作成する必要があります。それに続いて、再同期するときは PyDict_Clear、新しい辞書を再割り当てするのではなく、 を使用して、開始する前に辞書をクリアする必要があります。他に何も必要ありません。(コードで行っているように、新しいものを再割り当てする場合は、最初に古いものの参照カウントを減らす必要があります。しかし、古いものを参照する Python 側のコードは、古いものを参照し続けますPyDict_Clear。おそらくより良い解決策です。)

また、一時的な Python オブジェクトが関係する場所にも注意を払う必要があります。現時点では、ループ内で Python (および C) 関数のみを使用し、C++ 例外をトリガーできないため、他に何も必要ありません。コードをほんの少しだけ変更すると、そうではなくなる可能性があります。原則として、明示的に呼び出すのではなく、PyObject*デストラクタが を呼び出すクラスに をラップする必要があり、例外のために呼び出しを見逃す可能性があることがわかりました。Py_DecRef

于 2013-01-07T14:17:58.677 に答える