[PyQt] double free issue with OUT-argument
Diez B. Roggisch
deets at web.de
Sat Feb 13 17:34:58 GMT 2010
Hi,
wrapping happily away a 3D-engine, I encounter the following problem:
>>> import irrlicht
>>> core = irrlicht.irr.core
>>> q = core.quaternion()
>>> q.toEuler()
python(3701) malloc: *** error for object 0x474b70: double free
*** set a breakpoint in malloc_error_break to debug
(0.0, -0.0, 0.0)
This is the declaration of toEuler in .sip:
void toEuler(irr::core::vector3df& euler /Out/) const;
As you can see, it's supposed to modify a passed vector in place.
However, I declared vectors to be converted from & to tuples, by this
code mapping:
%MappedType irr::core::vector3df
{
%TypeHeaderCode
#include <vector3d.h>
%End
%ConvertFromTypeCode
if (!sipCpp)
return PyTuple_New(0);
irr::core::vector3df *v = (irr::core::vector3df *)sipCpp;
return PyTuple_Pack(3,
PyFloat_FromDouble(v->X),PyFloat_FromDouble(v->Y),PyFloat_FromDouble(v->Z));
%End
%ConvertToTypeCode
if (sipIsErr == NULL) {
if(PySequence_Check(sipPy) && PySequence_Length(sipPy) == 3) {
for(int j = 0; j < 3; j++) {
PyObject *v = PySequence_GetItem(sipPy, j);
if(!PyFloat_Check(v) && !PyInt_Check(v)) {
return false;
}
}
return true;
}
return false;
}
if (sipPy == Py_None) {
*sipCppPtr = NULL;
return 0;
}
irr::core::vector3df *v = new irr::core::vector3df();
PyErr_Clear();
irr::core::vector3df &t = *v;
if(PyArg_ParseTuple(sipPy, "fff", &t.X, &t.Y, &t.Z)) {
*sipCppPtr = v;
return 1;
} else {
delete v;
*sipIsErr = 1;
return 0;
}
%End
};
Looking at the generated code, it seems to me it is perfectly fine - it
creates a new vector instance, passes that in, converts it to a tuple,
and deletes it.
extern "C" {static PyObject *meth_irr_core_quaternion_toEuler(PyObject
*, PyObject *);}
static PyObject *meth_irr_core_quaternion_toEuler(PyObject *sipSelf,
PyObject *sipArgs)
{
int sipArgsParsed = 0;
{
irr::core::vector3df * a0;
irr::core::quaternion *sipCpp;
if
(sipParseArgs(&sipArgsParsed,sipArgs,"B",&sipSelf,sipType_irr_core_quaternion,&sipCpp))
{
PyObject *sipResult;
a0 = new irr::core::vector3df();
sipCpp->toEuler(*a0);
sipResult =
sipConvertFromNewType(a0,sipType_irr_core_vector3df,NULL);
delete a0;
return sipResult;
}
}
/* Raise an exception if the arguments couldn't be parsed. */
sipNoMethod(sipArgsParsed,sipName_quaternion,sipName_toEuler);
return NULL;
}
I don't understand the behavior - anything I miss?
Regards,
Diez
More information about the PyQt
mailing list