Sturla Molden skrev:
> cdef class membuffer:
>
> cdef readonly void *buf
> cdef readonly Py_ssize_t nbytes
>
> def __cinit__(membuffer self, Py_ssize_t nbytes):
> self.buf = stdlib.malloc(nbytes)
> if (self.buf == NULL):
> raise MemoryError, 'malloc failed'
> self.nbytes = nbytes
>
> def __dealloc__(membuffer self):
> if (self.buf): stdlib.free(self.buf)
>
This design pattern is very important, because is avoids accidental
memory leaks if an exception is raised. For the same reason, Python's C
API has CObjects for storing C objects. They are used like this
(ignoring error checking on malloc):
cdef extern from "Python.h":
object PyCObject_FromVoidPointer(void *cobj, void (*destr*)(void*))
void *PyCObject_AsVoidPointer(object self)
cdef object buf =
PyCObject_FromVoidPointer(stdlib.malloc(nbytes),stdlib.free)
cdef void *pbuf = PyCObject_AsVoidPointer(buf)
The advantage is, similar to the membuffer class above, that a matching
call to free is gurarranteed. If you just put calls to malloc/free
randomly into Cython, a portion of the code could be skipped when an
exception is raised, and a memory leak would result. Manual memory
management is more tricky than it appears on the surface.
In plain C, there are no exceptions, but you can still get the problem
if someone uses setjmp/longjmp. If you know there is no longjmps, you
can use malloc/free rather safely.
In C++ there are exceptions, and std::vector is therefore much safter
than operators new[] and delete[]. It is generally newer safe to use
new[] and delete[] outside constructors and destructors, and doing so is
the number one cause of memory leaks in C++. Unfortunately, C++ textbook
teach bad habits, including using operator new[] anywhere.
Cython is just like C++: you can get exceptions thrown! Therefore, put
all manual allocations in __cinit__ and all manual deallocations in
__dealloc__. That will prevent bad resource leaks in case of an
exception being raised. Just putting calls to malloc/free randomly into
Cython code is syntactially legal, but not a design pattern I would
recommend.
Sorry for ranting...
S.M.
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev