OK, I'm getting a strange error after using Cython's C++ support as I think the manual advises (to use __cinit__
to allocate heap RAM and __dealloc__
to free it again.
I have a C++ class which calloc
and malloc
s some RAM in its constructor and free
s it in the destructor. I will post this if necessary, but the error isn't coming from C++ land, and the new
and delete
calls work fine, so I'll just give you the cython for now:
cdef extern from "../clibs/adjacency.hpp":
cdef cppclass Adjacency:
int* _bv
void** _meta
unsigned int length
Adjacency(int graph_order, int meta_on)
int get(int i, int j)
void set(int i, int j, int on, void* meta)
void reset_to_zero()
void edges_iter(void* global_meta, void (*callback)(void*, int, int, void*))
cdef class Graph:
cdef Adjacency* adj
def __init__(self, graph_order):
print "__init__"
def __cinit__(self, graph_order, *args, **kwargs):
print "__cinit__"
print "allocating, no meta."
self.adj = new Adjacency(<int>graph_order, 0)
def __dealloc__(self):
print "__dealloc__"
del self.adj
When I test this, I get the following:
In [1]: import graph
In [2]: g = graph.Graph(302)
__cinit__
allocating, no meta.
__init__
In [3]: ^D
Do you really want to exit ([y]/n)?
__dealloc__
Python(7389,0x7fff70f9acc0) malloc: *** error for object 0x100defa08: incorrect
checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Abort trap
I also sometimes get a segfault instead of an incorrect checksum.
I cracked open the C++ file that cython generated and added the following around the delete
call:
/* "graph.pyx":75
* def __dealloc__(self):
* print "__dealloc__"
* del self.adj # <<<<<<<<<<<<<<
*
* def __init__(self, graph_order):
*/
printf("about to delete adj:\n");
delete __pyx_v_self->adj;
printf("just deleted adj!\n");
and we can clearly see that the call I made to delete
runs fine:
In [1]: import graph
In [2]: g = graph.Graph(302)
__cinit__
allocating, no meta.
__init__
In [3]: ^D
Do you really want to exit ([y]/n)?
__dealloc__
about to delete adj:
just deleted adj!
Python(7389,0x7fff70f9acc0) malloc: *** error for object 0x100defa08: incorrect
checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Abort trap
And that Python throws a tantrum after I'm done tidying up as I was told to in the Cython manual.
I also just tried setting self.adj = NULL
in __dealloc__
, in case Python was trying to see inside my object, but that didn't help.
Any ideas what I'm doing wrong?