[Pyrex] Resource freeing

Anders Waldenborg andersg at 0x63.nu
Wed Nov 19 10:05:57 CET 2008


How am I supposed to handle freeing of resources allocated from inside 
of python?


Lets look at some simple code:

cdef extern from "malloc.h":
     void *malloc(int)
     void free(void *)

def simple(x):
     cdef void *t

     t = malloc(10);
     ret = x + 1
     free(t)

     return ret



"ret = x + 1" translates into:

   /* "/tmp/pyrex-rl/test.pyx":10 */
   __pyx_1 = PyInt_FromLong(1); if (!__pyx_1) {__pyx_filename = 
__pyx_f[0]; __pyx_lineno = 10; goto __pyx_L1;}
   __pyx_2 = PyNumber_Add(__pyx_v_x, __pyx_1); if (!__pyx_2) 
{__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; goto __pyx_L1;}
...

Which will contains two gotos that will skip over the free call.

If I rewrite it to this:

def simple(x):
     cdef void *t

     t = malloc (10);

     try:
         ret = x + 1
     except:
         free (t)
         raise

     free (t)

     return ret

it gets much better. BUT there is still a path where it may not be 
freed; the except clause generates this code:

   /*except:*/ {
     __Pyx_AddTraceback("test.simple");
     if (__Pyx_GetException(&__pyx_1, &__pyx_2, &__pyx_3) < 0) 
{__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; goto __pyx_L1;}

     /* "/tmp/pyrex-rl/test.pyx":14 */
     free(__pyx_v_t);


Where the goto causes it to skip the free call.




More information about the Pyrex mailing list