2013-02-15 4 views
1

У меня есть код Cython, который на самом деле является оберткой для внешней библиотеки C, как описано в соответствующей документации и нескольких других источниках (например, here и here). У меня есть следующий Cython определение класса:Странное повреждение памяти при вызове внешней библиотеки C в оболочке Python

import numpy 
cimport numpy 
cimport clib # my C library 

cdef class DoStuff: 
    def __call__(self, array a): 
     cdef numpy.ndarray[float, ndim=1] npa = numpy.ascontiguousarray(a) 
     clib.cStuff(<float*>npa.data) 

Моя функция C (cStuff) всегда ведет себя, как ожидается, при компиляции и запуска в другом коде C, и его возвращаемые значения полностью определяются входом (без генерации случайных чисел вовлеченного). Он выделяет массивы с плавающей точкой в ​​куче, используя malloc(), и никогда не free() s, так как оба кода C и Python завершают выполнение после завершения cStuff. Однако, когда я вызываю функцию из Python иногда (например, 1 из 5), происходит повреждение памяти, а cStuff возвращает бессмысленные результаты, как если бы память, выделенная программой C, была перезаписана. Массив a не поврежден при вызове функции C, поскольку в любом случае правильные значения печатаются cStuff. Любая идея о том, что может это сделать? Спасибо

+0

Это легко возможно, что ваша библиотека C либо (а) не выделяет достаточно памяти, но и в вашей программе C всегда получает повезло, или (b) топает в стеке, но в вашей программе C так мало осталось сделать после возвращения из 'cStuff', что все работает в любом случае. Итак, только потому, что он «ведет себя так, как ожидалось», это не значит, что это правильно. – abarnert

+0

Также вы можете посмотреть код, созданный Cython, и сравнить, что он делает с вашей программой на C, и посмотреть, есть ли какие-либо очевидные различия. – abarnert

+0

Я тоже получаю эту проблему. Я работаю на C++. Я выделяю массив, используя 'new' в моей библиотеке. Затем я помещал в него данные. В Cython я копирую данные в массив numpy. Затем я вызываю библиотечную функцию, которая освобождает мой массив. Большую часть времени он работает отлично, но иногда я получу глупость. Это супер-странно, потому что на самом деле я создаю гистограмму. Поэтому некоторые характеристики гистограммы иногда остаются ... но иногда нет ... В конечном изображении легко увидеть, что какая-то коррупция произошла, но она не полностью вымыла мой массив. – Joel

ответ

2

Я не могу вывести из кода, где находится ваша проблема. Мне нужно больше контекста.

Вы пытались запустить это под Valgrind?

http://valgrind.org/info/tools.html#memcheck

Выполнить это так:

> valgrind python script.py

+0

Как правило, что-то вроде этого было бы лучше как комментарий, чем как ответ. Но в этом случае кажется, что было бы очень долго и гораздо труднее читать, комментировать, так что, возможно, это лучшая альтернатива. – abarnert

+0

Спасибо, я рассмотрю его как можно скорее – Clef