python — подсчет ссылок для функции c ++

Когда я запускаю этот код, у меня возникает проблема с памятью, поэтому я думаю, что я должен использовать 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;
}

-3

Решение

Я бы порекомендовал посмотреть документацию по каждому методу Python, который вы используете, чтобы понять, когда у вас есть объект Python или когда вы заимствуете его.

  1. pArgs создан с PyTuple_New(). Если вы не возвращаетесь pArgs (например, вы вернетесь NULL из-за ошибки), вы должны освободить свое право собственности с Py_DECREF(pArgs),

  2. pValue это временная переменная, используемая для хранения объекта python, поэтому мы вернемся к этому позже, когда он будет использован.

  3. tuplelist это массив объектов Python. Перед выходом из функции вы должны delete[] tuplelist (как указано user4815162342). Но прежде чем вы сможете удалить его, вы должны освободить любые объекты Python, которые он содержит, итерируя по нему Py_XDECREF(item) (Py_XDECREF() безопасно использовать на NULL указатели). (см. пул № 7)

  4. Предмет в tuplelist[j] создан с PyList_New(). Вы владеете предметом в tuplelist но выпустить ссылку см. в пуле № 7.

  5. pValue создан с PyString_FromString(). Вы владеете этой строкой. Тогда вы звоните PyList_SetItem(tuplelist\[j\], ..., pValue) который ворует собственность pValue от вас, что означает НЕ Py_DECREF(pValue),

  6. pValue создан с PyInt_FromLong(). У вас есть это целое число, но по телефону PyList_SetItem(tuplelist[j], ..., pValue) Ваша собственность на него украдена, поэтому вы не должны Py_DECREF(pValue),

  7. В конце концов, вы PyTuple_SetItem(pArgs, j, tuplelist[j]) который крадет собственность от tuplelist[j] что делает это сложно. Если вы потерпите неудачу рано с ошибкой (когда вы вернетесь NULL), вы должны только тогда Py_DECREF(tuplelist[j]) но не освобождайте предметы внутри tuplelist потому что любые предыдущие ссылки в нем заимствованы, потому что они были украдены.

1

Другие решения


По вопросам рекламы [email protected]