PyObject_CallObject code dump after calling 4 times
grbgooglefan
ganeshborse at gmail.com
Thu Jan 3 23:23:41 EST 2008
On Jan 3, 8:49 pm, grbgooglefan <ganeshbo... at gmail.com> wrote:
> On Jan 3, 8:02 pm, Phil Thompson <p... at riverbankcomputing.co.uk>
> 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);
//
================================================================================
More information about the Python-list
mailing list