Когда я запускаю этот код, у меня возникает проблема с памятью, поэтому я думаю, что я должен использовать PY_DECREF()
чтобы освободить память, но я не знаю, где ее поставить? Любая помощь ? Я пытался поставить его в конце кода, перед возвратом pArgs
но это не похоже на работу.
Этот код подготавливает аргумент, который отправляется функции Python, поэтому он заполняет pArgs
со счетными списками. Каждый список является аргументом функции python.
PyObject * Ecrire::getArgumentsbis(PythonRetour * pr){
int j = 0 ;
PyObject * pArgs = NULL;
int count=pr->numberargs;
pArgs = PyTuple_New(count);
PyObject * pValue;
PyObject ** tuplelist = new PyObject*[count];
for(j = 0; j < pr->numberargs; j++){
std::string argument = pr->nom_args[j];
int buffer = pr->buffer[j]+1;
tuplelist[j] = PyList_New(buffer);
if(ends_with_string(argument,"%#C#%"))
argument = argument.substr(0, argument.size()-5);
if(valeurs.size() >= buffer){
int l;
for(l = 0; l < buffer; l++){
map<std::string,pvalues>::const_iterator it = valeurs[valeurs.size() - 1 - l].find(argument);
if (it != valeurs[valeurs.size() - 1 - l].end()){
if(ends_with_string(pr->nom_args[j], "%#C#%")){
if((*it).second.type == "enumere"){
std::string valueread = (*it).second.val;
unsigned long long numberread;
istringstream(valueread) >> numberread;
std::map<std::string,inf_analyse>::const_iterator iter=mat->liste_analyse.find(argument);
if (iter != mat->liste_analyse.end()){
bool check = false;
std::string valuecorr = "";
int k = 0;
for(k=0;k<(*iter).second.nombre_valeurs;k++){
if((*iter).second.valeurs[k] == numberread) {
check = true;
valuecorr = (*iter).second.correspondances[k];
break;
}
}
if(check) {
pValue = PyString_FromString(valuecorr.c_str());
PyList_SetItem(tuplelist[j], buffer - l - 1, pValue);
}
else
return NULL;
}
}
}
else {
if((*it).second.type == "enumere"){
std::string valueread = (*it).second.val;
unsigned long long numberread;
istringstream(valueread) >> numberread;
pValue = PyInt_FromLong(numberread);
PyList_SetItem(tuplelist[j], buffer - l - 1, pValue);
}
else if((*it).second.type == "autre") {
std::string valueread = (*it).second.val;
double numberread;
istringstream(valueread) >> numberread;
pValue = Py_BuildValue("d", numberread);
PyList_SetItem(tuplelist[j], buffer - l - 1, pValue);
}
else if((*it).second.type == "chaine"){
std::string valueread = (*it).second.val;
pValue = PyString_FromString(valueread.c_str());
PyList_SetItem(tuplelist[j], buffer - l - 1, pValue);
}
}
}
else
return NULL;
}
}
else
return NULL;
PyTuple_SetItem(pArgs,j, tuplelist[j]);
}
return pArgs;
}
Я бы порекомендовал посмотреть документацию по каждому методу Python, который вы используете, чтобы понять, когда у вас есть объект Python или когда вы заимствуете его.
pArgs
создан с PyTuple_New()
. Если вы не возвращаетесь pArgs
(например, вы вернетесь NULL
из-за ошибки), вы должны освободить свое право собственности с Py_DECREF(pArgs)
,
pValue
это временная переменная, используемая для хранения объекта python, поэтому мы вернемся к этому позже, когда он будет использован.
tuplelist
это массив объектов Python. Перед выходом из функции вы должны delete[] tuplelist
(как указано user4815162342). Но прежде чем вы сможете удалить его, вы должны освободить любые объекты Python, которые он содержит, итерируя по нему (см. пул № 7)Py_XDECREF(item)
(Py_XDECREF()
безопасно использовать на NULL
указатели).
Предмет в tuplelist[j]
создан с PyList_New()
. Вы владеете предметом в tuplelist
но выпустить ссылку см. в пуле № 7.
pValue
создан с PyString_FromString()
. Вы владеете этой строкой. Тогда вы звоните PyList_SetItem(tuplelist\[j\], ..., pValue)
который ворует собственность pValue
от вас, что означает НЕ Py_DECREF(pValue)
,
pValue
создан с PyInt_FromLong()
. У вас есть это целое число, но по телефону PyList_SetItem(tuplelist[j], ..., pValue)
Ваша собственность на него украдена, поэтому вы не должны Py_DECREF(pValue)
,
В конце концов, вы PyTuple_SetItem(pArgs, j, tuplelist[j])
который крадет собственность от tuplelist[j]
что делает это сложно. Если вы потерпите неудачу рано с ошибкой (когда вы вернетесь NULL
), вы должны только тогда Py_DECREF(tuplelist[j])
но не освобождайте предметы внутри tuplelist
потому что любые предыдущие ссылки в нем заимствованы, потому что они были украдены.