好吧,我在使用Cython的C ++支持后遇到一个奇怪的错误,因为我认为manual advises(使用__cinit__
分配堆RAM而__dealloc__
再次释放它。< / p>
我有一个C ++类,calloc
和malloc
在构造函数中有一些RAM,而free
在析构函数中。如果有必要,我会发布这个,但错误不是来自C ++的土地,new
和delete
调用工作正常,所以我现在只给你cython:
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
当我测试时,我得到以下内容:
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
我有时也会得到段错误,而不是错误的校验和。
我破解了cython生成的C ++文件并在delete
调用周围添加了以下内容:
/* "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");
我们可以清楚地看到我对delete
的调用运行良好:
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
在我完成整理之后,我在Cython手册中告诉我,那个Python在之后引发了一个发脾气。
我也尝试在self.adj = NULL
中设置__dealloc__
,以防Python试图查看我的对象内部,但这没有帮助。
任何想法我做错了什么?
答案 0 :(得分:0)
我在我的C ++代码中犯了一个错误(我没有展示)。
我有很多这样的功能:
if (_meta != NULL) {
// do stuff with _meta, like loop over the void*s
}
但是在构造函数中,我在设置_meta = NULL;
...