On Jul 23, 2009, at 12:10 PM, Lisandro Dalcin wrote:

> On Thu, Jul 23, 2009 at 10:29 AM, Richard  
> Clarke<rscla...@gmail.com> wrote:
>> Thank you Robert, the explanation on how and where to use cdef was
>> most helpful.  I think it has just clicked(with a flag waving
>> 'idiot').
>>
>> The PyCObject concept is a nice idea, removing cdef foo_t *foo from
>> outside of __init__ ?  However, I see implications in memory
>> deallocation.  How does cython currently handle memory deallocation?
>
> I'm not sure you need PyCObject for your code ...

For sure PyCObject is not needed here. I was musing about a ptr <->  
object conversion happening automatically via PyCObject, just as we  
handle the more basic numeric types. Deallocation of pointers needs  
to be handled by the user explicitly, so perhaps it's not a good idea  
to make this transparently easy.

>
>>
>> I assume the best practice would be for users to deallocate memory in
>> the class __del__ method (calling the appropriate wrapped c library
>> destructor).
>
> Yes. More specifically, you should allocate stuff in __cinit__(), and
> deallocate stuff in __dealloc__()...

+1. To clarify, __cinit__ is called exactly once per object creation  
(no such guarantee with __init__). Likewise, __dealloc__ is always  
called exactly once upon collection. This makes memory management  
easy--essentially you're boostrapping of Python's refcounting.

>
>
>>  Otherwise does cython simply free(foo) or interprets the
>> language to build a depth first deallocation method?
>
> Cython does not manage memory allocated with malloc()... you have to
> manage deallocation yourself...
>
>
>>  I guess it
>> should do the simplest free(foo), if the developer was lazy not to
>> deallocate memory, they can suffer with memory leaks.  I think I  
>> might
>> have answered my own question here...
>>
>
> In short, you have to modify your class, using something like this
>
> cdef class Bar: # NOTE: "cdef" class
>
>     cdef foo_t *c_foo # NOTE: "cdef" instance (not class) member!!!
>
>     def __cinit__(self): # NOTE: using "__cinit__", not "__init__"
>         self.c_foo = self.c_open()
>
>     def __dealloc__(self): # NOTE: using "__dealloc__", not "__del__"
>         if self.c_foo != NULL:
>             free(self.c_foo)
>
>     cdef foo_t* c_open(self): # NOTE: using "cdef", not "def", this
> method will not show-up on Python side, it is a kind of internal,
> private method.
>         cdef foo_t *foo = NULL
>         foo = init()
>         return foo
>
>
> -- 
> Lisandro Dalcín
> ---------------
> Centro Internacional de Métodos Computacionales en Ingeniería (CIMEC)
> Instituto de Desarrollo Tecnológico para la Industria Química (INTEC)
> Consejo Nacional de Investigaciones Científicas y Técnicas (CONICET)
> PTLC - Güemes 3450, (3000) Santa Fe, Argentina
> Tel/Fax: +54-(0)342-451.1594
> _______________________________________________
> Cython-dev mailing list
> Cython-dev@codespeak.net
> http://codespeak.net/mailman/listinfo/cython-dev

_______________________________________________
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to