2014-06-12 66 views
-3

當我運行此代碼時,我遇到了內存問題,所以我認爲我應該使用PY_DECREF()來釋放內存,但我不知道該把它放在哪裏?任何幫助?我試圖把它放在代碼的末尾,在返回pArgs之前,但它似乎不起作用。C++函數的引用計數

此代碼準備發送到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

在退出函數之前,您肯定缺少delete [] tuplelist'。 – user4815162342

+0

我知道我添加刪除tuplelist,但它似乎並沒有解決問題。我需要添加一些Py_DECREF肯定 – user3516044

回答

1

我建議在看您所用的,當你擁有一個Python對象理解或當你借用一個Python的每個方法的文檔。

  1. pArgs使用PyTuple_New()創建。如果你沒有返回pArgs(例如,你回來,因爲一個錯誤的NULL),你必須釋放你的所有權Py_DECREF(pArgs)

  2. pValue是一個臨時變量,用於容納python對象,所以我們稍後會在它使用時回來。

  3. tuplelist是一個python對象數組。在退出該功能之前,您必須(如user4815162342所指出的那樣)。 但是在刪除它之前,您必須通過遍歷它來釋放它所保存的任何python對象。Py_XDECREF(item)Py_XDECREF()可安全地在NULL指針上使用)。(see bullet#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. 最後你偷了從tuplelist[j]竊取所有權,這使得這個棘手。如果你有一個錯誤(當你回到NULL)早期失敗,則必須只Py_DECREF(tuplelist[j])但沒有在tuplelist因爲在它之前的任何引用都是借來的,因爲他們竊取FREE的對象。

+0

謝謝。當我補充一點: 爲(H = 0; H <計數; H ++)Py_XDECREF(tuplelist並[h]); delete [] tuplelist; 我得到了一個異常時,我打電話與pArgs的功能,但如果我評論了符合日py_XDECREF,eveything運行良好。 – user3516044

+0

@ user3516044如果您還沒有'PyTuple_SetItem()''爲tuplelist [J]'你遇到一個錯誤,只有你想只'Py_DECREF(tuplelist [J])'。如果一切順利,那麼不要將'tuplelist'中的任何項目遞減,只需'delete [] tuplelist'。 – cpburnz

+0

你是一個耐心的人。 :)但是,如果沒有遇到錯誤,唯一缺少的部分是'delete [] tuplelist'。 (實際上,'tuplelist'根本就不是必需的,OP可以在創建時將對象直接保存到'pArgs'中。)一旦添加完成,內存問題可能是程序其他部分的錯誤。 – user4815162342