Мне интересно, как справиться со следующей проблемой. Внутри моего класса 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
и затем перераспределить это снова? Кто-то предлагает другой подход?
Мне не понятно, почему вы используете словарь в Python,
когда вы индексируете с непрерывным набором целых чисел, начиная с 0.
Однако, прежде чем использовать его, вам придется сделать PyDict_New
в
создать словарь. После этого при повторной синхронизации вы
следует очистить словарь перед запуском, используя
PyDict_Clear
, а не перераспределить новый .. Ничего другого
должно быть необходимо. (Если вы перераспределяете новый, как вы делаете в
ваш код, вы должны уменьшить счетчик ссылок на старый
один первый. Но любой код на стороне Python, который ссылается на
старый будет продолжать ссылаться на старый; PyDict_Clear
является
наверное лучшее решение.)
Также стоит обратить внимание, где временные объекты Python
вовлечены. На данный момент больше ничего не нужно, потому что
в цикле вы используете только функции Python (и, следовательно, C), и
они не могут вызвать исключение C ++. Измените код когда-либо
немного, и это может перестать иметь место. Как общее правило,
Я обнаружил, что вы должны обернуть PyObject*
в классе которого
вызовы деструкторов Py_DecRef
вместо того, чтобы называть это явно,
и, возможно, пропустить звонок из-за исключения.
Других решений пока нет …