Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Swaney <sswaney@centurytel.net>2004-10-13 03:58:03 +0400
committerStephen Swaney <sswaney@centurytel.net>2004-10-13 03:58:03 +0400
commitb711409f8d47b6b5466776876bfbb382f309f7dc (patch)
tree4d867cb5a8622b0f68ba38a12eb24312667dfc6b /source/blender/python/api2_2x/quat.c
parent4e8b2babdc0bf16b930f561af95069e2d2c8a8e1 (diff)
fix numerous memory leaks in the math types.
fixed bug: #1633 Memory leak in M_Mathutils_Vector The math types ( matrix, vector, quad ) now make copies of data passed to them rather than holding a pointer to memory that cannot be freed, or that may go away unexpectedly. This also clarifies the problem of who is responsible for freeing memory allocations. Pre-checkin files are tagged mem_leak-1 in case this breaks something.
Diffstat (limited to 'source/blender/python/api2_2x/quat.c')
-rw-r--r--source/blender/python/api2_2x/quat.c59
1 files changed, 43 insertions, 16 deletions
diff --git a/source/blender/python/api2_2x/quat.c b/source/blender/python/api2_2x/quat.c
index 2432a3c1f5e..a6974ef5086 100644
--- a/source/blender/python/api2_2x/quat.c
+++ b/source/blender/python/api2_2x/quat.c
@@ -150,14 +150,16 @@ PyObject *Quaternion_Conjugate( QuaternionObject * self )
static void Quaternion_dealloc( QuaternionObject * self )
{
+ PyMem_Free( self->quat );
PyObject_DEL( self );
}
static PyObject *Quaternion_getattr( QuaternionObject * self, char *name )
{
double mag = 0.0f;
- float *vec;
+ float *vec = NULL;
int x;
+ PyObject *retval;
if( ELEM4( name[0], 'w', 'x', 'y', 'z' ) && name[1] == 0 ) {
return PyFloat_FromDouble( self->quat[name[0] - 'w'] );
@@ -186,7 +188,9 @@ static PyObject *Quaternion_getattr( QuaternionObject * self, char *name )
vec[x] = ( self->quat[x + 1] / ( ( float ) ( mag ) ) );
}
Normalise( vec );
- return ( PyObject * ) newVectorObject( vec, 3 );
+ retval = ( PyObject * ) newVectorObject( vec, 3 );
+ PyMem_Free( vec );
+ return retval;
}
return Py_FindMethod( Quaternion_methods, ( PyObject * ) self, name );
}
@@ -334,7 +338,8 @@ static PyObject *Quaternion_repr( QuaternionObject * self )
PyObject *Quaternion_add( PyObject * q1, PyObject * q2 )
{
- float *quat;
+ float *quat = NULL;
+ PyObject *retval;
int x;
if( ( !QuaternionObject_Check( q1 ) )
@@ -353,12 +358,15 @@ PyObject *Quaternion_add( PyObject * q1, PyObject * q2 )
( ( ( QuaternionObject * ) q2 )->quat[x] );
}
- return ( PyObject * ) newQuaternionObject( quat );
+ retval = ( PyObject * ) newQuaternionObject( quat );
+ PyMem_Free( quat );
+ return retval;
}
PyObject *Quaternion_sub( PyObject * q1, PyObject * q2 )
{
- float *quat;
+ float *quat = NULL;
+ PyObject *retval;
int x;
if( ( !QuaternionObject_Check( q1 ) )
@@ -376,12 +384,16 @@ PyObject *Quaternion_sub( PyObject * q1, PyObject * q2 )
( ( ( QuaternionObject * ) q1 )->quat[x] ) -
( ( ( QuaternionObject * ) q2 )->quat[x] );
}
- return ( PyObject * ) newQuaternionObject( quat );
+ retval = ( PyObject * ) newQuaternionObject( quat );
+
+ PyMem_Free( quat );
+ return retval;
}
PyObject *Quaternion_mul( PyObject * q1, PyObject * q2 )
{
- float *quat;
+ float *quat = NULL;
+ PyObject *retval;
int x;
if( ( !QuaternionObject_Check( q1 ) )
@@ -400,15 +412,18 @@ PyObject *Quaternion_mul( PyObject * q1, PyObject * q2 )
( ( QuaternionObject * ) q1 )->quat[x] *
( ( QuaternionObject * ) q2 )->quat[x];
}
- return ( PyObject * ) newQuaternionObject( quat );
+ retval = ( PyObject * ) newQuaternionObject( quat );
+
+ PyMem_Free( quat );
+ return retval;
}
//coercion of unknown types to type QuaternionObject for numeric protocols
int Quaternion_coerce( PyObject ** q1, PyObject ** q2 )
{
- long *tempI;
- double *tempF;
- float *quat;
+ long *tempI = NULL;
+ double *tempF = NULL;
+ float *quat = NULL;
int x;
if( QuaternionObject_Check( *q1 ) ) {
@@ -429,8 +444,9 @@ int Quaternion_coerce( PyObject ** q1, PyObject ** q2 )
}
PyMem_Free( tempI );
*q2 = newQuaternionObject( quat );
+ PyMem_Free( quat );
( ( QuaternionObject * ) * q2 )->flag = 1; //int coercion
- Py_INCREF( *q1 );
+ Py_INCREF( *q1 ); /* fixme: is this needed? */
return 0;
} else if( PyFloat_Check( *q2 ) ) { //cast scalar to Quaternion
tempF = PyMem_Malloc( 1 *
@@ -444,14 +460,15 @@ int Quaternion_coerce( PyObject ** q1, PyObject ** q2 )
}
PyMem_Free( tempF );
*q2 = newQuaternionObject( quat );
+ PyMem_Free( quat );
( ( QuaternionObject * ) * q2 )->flag = 2; //float coercion
- Py_INCREF( *q1 );
+ Py_INCREF( *q1 ); /* fixme: is this needed? */
return 0;
}
}
//unknown type or numeric cast failure
printf( "attempting quaternion operation with unsupported type...\n" );
- Py_INCREF( *q1 );
+ Py_INCREF( *q1 ); /* fixme: is this needed? */
return 0; //operation will type check
}
} else {
@@ -514,6 +531,13 @@ PyTypeObject quaternion_Type = {
&Quaternion_SeqMethods, /*tp_as_sequence */
};
+/*
+ newQuaternionObject
+
+ if the quat arg is not null, this method allocates memory and copies *quat into it.
+ we will free the memory in the dealloc routine.
+*/
+
PyObject *newQuaternionObject( float *quat )
{
QuaternionObject *self;
@@ -523,14 +547,17 @@ PyObject *newQuaternionObject( float *quat )
self = PyObject_NEW( QuaternionObject, &quaternion_Type );
+ self->quat = PyMem_Malloc( 4 * sizeof( float ) );
+
if( !quat ) {
- self->quat = PyMem_Malloc( 4 * sizeof( float ) );
for( x = 0; x < 4; x++ ) {
self->quat[x] = 0.0f;
}
self->quat[3] = 1.0f;
} else {
- self->quat = quat;
+ for( x = 0; x < 4; x++ ) {
+ self->quat[x] = quat[x];
+ }
}
self->flag = 0;