2014-06-12 3 views
-3

이 코드를 실행하면 메모리를 확보하기 위해 PY_DECREF()을 사용해야한다고 생각하지만 메모리에 문제가 있습니다.하지만 그 위치를 알 수는 없습니까? 어떤 도움이 필요합니까? pArgs을 반환하기 직전에 코드의 끝에 넣으려고했지만 작동하지 않는 것 같습니다.C++ 함수에 대한 참조 계산

이 코드는 숫자 목록으로 pArgs을 채울 수 있도록 파이썬 함수로 전송되는 인수를 준비합니다. 각 목록은 파이썬 함수의 인수입니다.

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

삭제 튜플리스트를 추가했는데 문제가 해결되지 않는 것 같습니다. 확실히 Py_DECREF를 추가해야합니다. – user3516044

답변

1

파이썬 개체를 소유하고 있거나 빌릴 때를 이해하는 데 사용하는 각 파이썬 메서드에 대한 설명서를 살펴 보는 것이 좋습니다.

  1. pArgsPyTuple_New()으로 생성됩니다. pArgs을 반환하지 않는 경우 (예 : 오류로 인해 NULL을 반환하는 경우) 소유권을 해제해야합니다 (Py_DECREF(pArgs)).

  2. pValue은 파이썬 개체를 보관하는 데 사용되는 임시 변수이므로 나중에 사용할 때 다시 사용하겠습니다.

  3. tuplelist은 파이썬 개체의 배열입니다. 함수를 종료하기 전에 (user4815162342으로 지적한대로)을 사용해야합니다. 하지만 삭제하기 전에 보유하고있는 모든 파이썬 객체를 반복해야합니다 (NULL 포인터에서 (Py_XDECREF()은 안전합니다)). (글 머리 기호 # 7 참조)

  4. tuplelist[j]의 항목은 PyList_New()으로 생성됩니다. tuplelist에있는 항목을 소유하고 있지만 참조 번호를 공개하려면 글 머리 기호 # 7을 참조하십시오.

  5. pValuePyString_FromString()으로 생성됩니다. 당신은이 문자열을 소유하고 있습니다. 그런 다음 pValue의 소유권을 훔치는 PyList_SetItem(tuplelist\[j\], ..., pValue)으로 전화하면됩니다. 즉, Py_DECREF(pValue)이 아닙니다.

  6. pValuePyInt_FromLong()으로 생성됩니다. 이 정수를 소유하고 있지만 PyList_SetItem(tuplelist[j], ..., pValue)으로 소유권을 소유하면 도난 당하므로 Py_DECREF(pValue)이 아니어야합니다.

  7. 너는 tuplelist[j]에서 소유권을 훔치는 PyTuple_SetItem(pArgs, j, tuplelist[j]) 이니 까다 롭다. 오류가 발생하여 일찍 실패하면 (NULL을 반환 할 때) Py_DECREF(tuplelist[j]) 만 허용해야합니다. 그러나 도난 당했기 때문에 이전 참조가 차용되었으므로 tuplelist 안에있는 객체를 해제하지 마십시오.

+0

감사합니다. 내가 이것을 추가 할 때 : (h = 0; h user3516044

+0

@ user3516044 아직'tuplelist [j]'에'PyTuple_SetItem()'을하지 않았고 에러가 발생하면'Py_DECREF (tuplelist [j])'만하고 싶습니다.모든 것이 성공하면,'tuplelist'에있는 어떤 아이템도''delete [] tuplelist'' 만 지정하면 안됩니다. – cpburnz

+0

당신은 환자입니다. :) 그러나 오류가 발생하지 않은 경우, 누락 된 유일한 부분은'delete [] tuplelist'입니다. 사실,'tuplelist'는 전혀 필요하지 않습니다. OP는 객체가 생성 될 때 객체를'pArgs '에 직접 저장할 수 있습니다.) 일단 추가되면, 메모리 문제는 프로그램의 다른 부분의 오류 일 가능성이 높습니다. – user4815162342

관련 문제