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/vector.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/vector.c')
-rw-r--r--source/blender/python/api2_2x/vector.c71
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;