Класс расширения Cython: «неверная контрольная сумма для освобожденного объекта» после метода __dealloc__

ОК, я получаю странную ошибку после использования поддержки C ++ в Cython, так как руководство советует (использовать __cinit__ выделить кучу оперативной памяти и __dealloc__ чтобы освободить его снова.

У меня есть класс C ++, который calloc а также mallocнемного ОЗУ в своем конструкторе и freeв деструкторе. Я опубликую это в случае необходимости, но ошибка не исходит от земли C ++, и new а также delete вызовы работают нормально, поэтому я покажу вам только цитон:

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

Я также иногда получаю сигфо вместо неверной контрольной суммы.

Я открыл файл C ++, сгенерированный Cython, и добавил следующее: 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.

Я тоже только что попробовал установить self.adj = NULL в __dealloc__В случае, если Python пытался увидеть внутри моего объекта, но это не помогло.

Есть идеи, что я делаю не так?

1

Решение

Я допустил ошибку в своем коде C ++ (который я не показывал).

У меня было несколько таких функций:

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

Но в конструкторе я вызывал один из них перед установкой _meta = NULL;

0

Другие решения

Других решений пока нет …