c++ - Cython 扩展类 : "incorrect checksum for freed object" after __dealloc__ method

标签 c++ python cython

好的,在使用 Cython 的 C++ 支持后,我遇到了一个奇怪的错误,因为我认为 manual advises (使用 __cinit__ 分配堆 RAM 并使用 __dealloc__ 再次释放它。

我有一个 C++ 类,它在其构造函数中callocmalloc 一些 RAM,并在析构函数中释放它。如有必要,我会发布这个,但错误不是来自 C++ 领域,newdelete 调用工作正常,所以我只给你 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 发脾气。

我还尝试在 __dealloc__ 中设置 self.adj = NULL,以防 Python 试图查看我的对象内部,但这没有帮助。

知道我做错了什么吗?

最佳答案

我在我的 C++ 代码中犯了一个错误(我没有显示)。

我有一堆这样的函数:

if (_meta != NULL) {
  // do stuff with _meta, like loop over the void*s
}

但是在构造函数中,我在设置 _meta = NULL; 之前调用了其中一个 ...

关于c++ - Cython 扩展类 : "incorrect checksum for freed object" after __dealloc__ method,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14115121/

相关文章:

c++ - 在 C++ 接口(interface)中声明模板函数?

python - 如何在具有通用浮点类型的cython中声明一个ndarray

Cythonize 以 'fatal error C1002: compiler is out of heap space in pass 2' 结尾

python - 从 HDF5 文件中删除数据集属性

python - Flask-Dance错误: Scope has changed

python - Cython - 如何使用引用正确调用运算符

c++ - 将字符串转换为变量名或变量类型

c++ - 减去 std::strings 时出现编译器错误

c++ - C++ 中的 Matlab 类型转换

python - 使用 XLRD 迭代列中的行