diff options
author | Stephen Swaney <sswaney@centurytel.net> | 2004-10-13 03:58:03 +0400 |
---|---|---|
committer | Stephen Swaney <sswaney@centurytel.net> | 2004-10-13 03:58:03 +0400 |
commit | b711409f8d47b6b5466776876bfbb382f309f7dc (patch) | |
tree | 4d867cb5a8622b0f68ba38a12eb24312667dfc6b /source/blender/python/api2_2x/vector.c | |
parent | 4e8b2babdc0bf16b930f561af95069e2d2c8a8e1 (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/vector.c')
-rw-r--r-- | source/blender/python/api2_2x/vector.c | 71 |
1 files changed, 46 insertions, 25 deletions
diff --git a/source/blender/python/api2_2x/vector.c b/source/blender/python/api2_2x/vector.c index aefa5dfb821..83da130b8fd 100644 --- a/source/blender/python/api2_2x/vector.c +++ b/source/blender/python/api2_2x/vector.c @@ -392,6 +392,7 @@ PyObject *Vector_add( PyObject * v1, PyObject * v2 ) { float *vec; int x; + PyObject *retval; if( ( !VectorObject_Check( v1 ) ) || ( !VectorObject_Check( v2 ) ) ) return EXPP_ReturnPyObjError( PyExc_TypeError, @@ -413,15 +414,18 @@ PyObject *Vector_add( PyObject * v1, PyObject * v2 ) ( ( VectorObject * ) v2 )->vec[x]; } - return ( PyObject * ) newVectorObject( vec, - ( ( ( VectorObject * ) v1 )-> - size ) ); + retval = ( PyObject * ) newVectorObject( vec, + ( ( ( VectorObject * ) v1 )-> + size ) ); + PyMem_Free( vec ); + return retval; } PyObject *Vector_sub( PyObject * v1, PyObject * v2 ) { float *vec; int x; + PyObject *retval; if( ( !VectorObject_Check( v1 ) ) || ( !VectorObject_Check( v2 ) ) ) return EXPP_ReturnPyObjError( PyExc_TypeError, @@ -443,15 +447,18 @@ PyObject *Vector_sub( PyObject * v1, PyObject * v2 ) ( ( VectorObject * ) v2 )->vec[x]; } - return ( PyObject * ) newVectorObject( vec, - ( ( ( VectorObject * ) v1 )-> - size ) ); + retval = ( PyObject * ) newVectorObject( vec, + ( ( ( VectorObject * ) v1 )-> + size ) ); + PyMem_Free( vec ); + return retval; } PyObject *Vector_mul( PyObject * v1, PyObject * v2 ) { float *vec; int x; + PyObject *retval; if( ( !VectorObject_Check( v1 ) ) || ( !VectorObject_Check( v2 ) ) ) return EXPP_ReturnPyObjError( PyExc_TypeError, @@ -473,15 +480,18 @@ PyObject *Vector_mul( PyObject * v1, PyObject * v2 ) ( ( VectorObject * ) v2 )->vec[x]; } - return ( PyObject * ) newVectorObject( vec, - ( ( ( VectorObject * ) v1 )-> - size ) ); + retval = ( PyObject * ) newVectorObject( vec, + ( ( ( VectorObject * ) v1 )-> + size ) ); + PyMem_Free( vec ); + return retval; } PyObject *Vector_div( PyObject * v1, PyObject * v2 ) { float *vec; int x; + PyObject *retval; if( ( !VectorObject_Check( v1 ) ) || ( !VectorObject_Check( v2 ) ) ) return EXPP_ReturnPyObjError( PyExc_TypeError, @@ -507,9 +517,11 @@ PyObject *Vector_div( PyObject * v1, PyObject * v2 ) ( ( VectorObject * ) v2 )->vec[x]; } - return ( PyObject * ) newVectorObject( vec, - ( ( ( VectorObject * ) v1 )-> - size ) ); + retval = ( PyObject * ) newVectorObject( vec, + ( ( ( VectorObject * ) v1 )-> + size ) ); + PyMem_Free( vec ); + return retval; } //coercion of unknown types to type VectorObject for numeric protocols @@ -522,7 +534,7 @@ int Vector_coerce( PyObject ** v1, PyObject ** v2 ) if( VectorObject_Check( *v1 ) ) { if( VectorObject_Check( *v2 ) ) { //two vectors - Py_INCREF( *v1 ); + Py_INCREF( *v1 ); /* fixme: wahy are we bumping the ref count? */ Py_INCREF( *v2 ); return 0; } else { @@ -540,9 +552,8 @@ int Vector_coerce( PyObject ** v1, PyObject ** v2 ) v1 )->size ) * sizeof( float ) ); for( x = 0; - x < - ( ( ( VectorObject * ) * - v1 )->size ); x++ ) { + x < ( ( ( VectorObject * ) * v1 )->size ); + x++ ) { vec[x] = ( float ) *tempI; } PyMem_Free( tempI ); @@ -641,11 +652,19 @@ PyTypeObject vector_Type = { /* - * create a Vector Object - * if vec arg is NULL - * allocate memory on python stack. - * initialize to zero in homogenous coords. + * create a Vector Object( vec, size ) + * + * Note: Vector now uses copy semantics like STL containers. + * Memory for vec member is allocated on python stack. + * We own this memory and will free it later. + * * size arg is number of floats to alloc. + * + * if vec arg is NULL + * fill our vec with zeros + * initialize 4d vectors to zero in homogenous coords. + * else + * vec param is copied into our local memory and always freed. */ PyObject *newVectorObject( float *vec, int size ) @@ -657,17 +676,19 @@ PyObject *newVectorObject( float *vec, int size ) self = PyObject_NEW( VectorObject, &vector_Type ); + self->vec = PyMem_Malloc( size * sizeof( float ) ); + self->delete_pymem = 1; /* must free this alloc later */ + if( !vec ) { - self->vec = PyMem_Malloc( size * sizeof( float ) ); for( x = 0; x < size; x++ ) { self->vec[x] = 0.0f; } - if( size == 4 ) + if( size == 4 ) /* do the homogenous thing */ self->vec[3] = 1.0f; - self->delete_pymem = 1; /* must free this alloc later */ } else { - self->vec = vec; - self->delete_pymem = 0; + for( x = 0; x < size; x++ ){ + self->vec[x] = vec[x]; + } } self->size = size; |