On Jan 3, 8:49 pm, grbgooglefan <[EMAIL PROTECTED]> wrote: > On Jan 3, 8:02 pm, Phil Thompson <[EMAIL PROTECTED]> > wrote: > > > > > > > On Thursday 03 January 2008, grbgooglefan wrote: > > > > I have a following C++ code which uses PyObject_CallObject to evaluate > > > expressions dynamically. This code sets the input parameters for the > > > function also dynamically. After calling this function 4 times (with > > > these shown values), PyObject_CallObject causes application to crash > > > in frame_dealloc. > > > 1) Can some one please help me understand why is this crash happening > > > in frame_dealloc & how to solve it? > > > 2) Is there anything wrong I am doing about incrementing or > > > decrementing the reference counts of the object passed to > > > PyObject_CallObject? > > > Yes. > > > > 3) Is it because of the big value (2299265.500000) I am trying to > > > convert from double to float using PyFloat_FromDouble? > > > > //========================= code reduced for readability > > > =============== > > > switch(ndtyp){ > > > case(INT_T): > > > { > > > printf("PyInt_FromLong val %d, var %s > > > \n",inputVar.nionum,pEvalFunc->pExprVarsArray[nCtr].szVarName); > > > val = PyInt_FromLong(inputVar.nionum); > > > break; > > > } > > > case(LONG_T): > > > { > > > printf("PyLong_FromLong val %ld, var %s > > > \n",inputVar.lionum,pEvalFunc->pExprVarsArray[nCtr].szVarName); > > > val = PyLong_FromLong(inputVar.lionum); > > > break; > > > } > > > case(FLOAT_T): > > > { > > > printf("PyFloat_FromDouble val %f, var %s > > > \n",inputVar.fionum,pEvalFunc->pExprVarsArray[nCtr].szVarName); > > > val = PyFloat_FromDouble(inputVar.fionum); > > > break; > > > } > > > case(DOUBLE_T): > > > { > > > printf("PyFloat_FromDouble val %f, var %s > > > \n",inputVar.dionum,pEvalFunc->pExprVarsArray[nCtr].szVarName); > > > val = PyFloat_FromDouble(inputVar.dionum); > > > break; > > > } > > > case(STRING_T): > > > { > > > printf("PyString_FromString val %s, var %s > > > \n",inputVar.ioString,pEvalFunc->pExprVarsArray[nCtr].szVarName); > > > val = PyString_FromString(inputVar.ioString); > > > break; > > > } > > > default: > > > printf("Unknown data type [%d] for %s\n",ndtyp,pEvalFunc- > > > > >pExprVarsArray[nCtr].szVarName); > > > > } > > > if(!val){ > > > ret = -1; > > > printf("Failed to convert %d %s to PyObject\n",ndtyp,pEvalFunc- > > > > >pExprVarsArray[nCtr].szVarName); fflush(stdout); > > > > Py_XDECREF(pTuple); > > > break; > > > } > > > PyTuple_SetItem(pTuple, nCtr, val); > > > Py_XDECREF(val); > > > Don't do this - PyTuple_SetItem() steals a reference to val. > > > > } > > > // all variables are set, call Python function > > > Py_XINCREF(pTuple); > > > Why do this? > > > > PyObject *pResult = PyObject_CallObject(pEvalFunc- > > > > >pPyEvalFunction,pTuple); > > > > Py_XDECREF(pTuple); > > > Why do this? > > > > if(PyErr_Occurred()){ > > > PyErr_Print(); > > > } else { > > > char* plevel = NULL; > > > if(NULL != (plevel = PyString_AsString(pResult))){ > > > ret = 0; > > > sprintf(szEvalResult,"%s",plevel); > > > } > > > } > > > Py_XDECREF(pResult); > > > pTuple will now have the same number of references as when you started the > > above code, so you may want to Py_DECREF() it. > > > Phil- Hide quoted text - > > > - Show quoted text - > > Thanks for all the responses. > These help me. > I could simulate this crash in my small test program & I think (I > could be wrong also) it is because of extraneous Py_XDECREF of > "PyObject *val" which I am using to convert variables to tuple. > When I change the code to simple do like this, it works fine. > PyTuple_SetItem(pytuple,0,PyLong_FromLong(size)); > PyTuple_SetItem(pytuple,1,PyLong_FromLong(maxvol)); > PyTuple_SetItem(pytuple,2,PyFloat_FromDouble(adv));- Hide quoted > text - > > - Show quoted text -
Now my new code looks like this. Do you think this is correct way to handle ref counts? Do you forsee any issues of memory leaks, etc. here? // ================================================================================ switch(ndtyp){ case(INT_T): //printf("PyInt_FromLong val %d, var %s \n",inputVar.nionum,pEvalFunc->pExprVarsArray[nCtr].szVarName); PyTuple_SetItem(pTuple,nCtr,PyInt_FromLong(inputVar.nionum)); break; case(LONG_T): //printf("PyLong_FromLong val %ld, var %s \n",inputVar.lionum,pEvalFunc->pExprVarsArray[nCtr].szVarName); PyTuple_SetItem(pTuple,nCtr,PyLong_FromLong(inputVar.lionum)); break; case(FLOAT_T): //printf("PyFloat_FromDouble val %f, var %s \n",inputVar.fionum,pEvalFunc->pExprVarsArray[nCtr].szVarName); PyTuple_SetItem(pTuple,nCtr,PyFloat_FromDouble(inputVar.fionum)); break; case(DOUBLE_T): //printf("PyFloat_FromDouble val %f, var %s \n",inputVar.dionum,pEvalFunc->pExprVarsArray[nCtr].szVarName); PyTuple_SetItem(pTuple,nCtr,PyFloat_FromDouble(inputVar.dionum)); break; case(STRING_T): //printf("PyString_FromString val %s, var %s \n",inputVar.ioString,pEvalFunc->pExprVarsArray[nCtr].szVarName); PyTuple_SetItem(pTuple,nCtr,PyString_FromString(inputVar.ioString)); break; default: printf("Unknown data type [%d] for %s \n",ndtyp,pEvalFunc->pExprVarsArray[nCtr].szVarName); bUnknownDataType = true; break; } if(bUnknownDataType){ // got an unknown data type for a variable ret = -1; break; } } // all variables are set, call Python function if(ret == 0){ PyObject *pResult = PyObject_CallObject(pEvalFunc- >pPyEvalFunction,pTuple); if(PyErr_Occurred()){ ret = -1; printf("error occured in PyObject_CallObject\n"); PyErr_Print(); } else { char* plevel = NULL; if(NULL != (plevel = PyString_AsString(pResult))){ ret = 0; strncpy(szEvalResult,plevel,strlen(plevel)); printf("Final result %s\n",szEvalResult); } else { printf("PyObject_CallObject returned NULL\n"); ret = -1; } } Py_XDECREF(pResult); Py_XDECREF(pTuple); // ================================================================================ -- http://mail.python.org/mailman/listinfo/python-list