当我运行此代码时,我的内存有问题,所以我认为我应该使用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;
}
答案 0 :(得分:1)
我建议您查看每个Python方法的文档,以便在拥有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
中的对象,因为之前的任何引用都是借用的,因为它们是被盗。