c ++函数的引用计数

时间:2014-06-12 13:05:50

标签: python c++ cpython reference-counting

当我运行此代码时,我的内存有问题,所以我认为我应该使用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;
}

1 个答案:

答案 0 :(得分:1)

我建议您查看每个Python方法的文档,以便在拥有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中的对象,因为之前的任何引用都是借用的,因为它们是被盗。