Я относительно новичок в C-расширениях для python. Я написал расширение, которое показывает поведение, которое кажется мне странным. Когда я запускаю скрипт python с помощью этого расширения, скрипт останавливается случайным образом после, процедура в расширениях была успешно выполнена. То есть, у меня есть сценарий, как:Функция в расширении C случайным образом останавливает выполнение программы python
import FlowCalc
import numpy as np
np.random.seed(1)
lakeNr = 6
trialNr = 10
a = np.round(np.random.rand(trialNr, lakeNr)).astype(int)
b = np.ones(shape=(lakeNr, lakeNr), dtype=float)
x = FlowCalc.flowCalc(a, b)
print(x)
for i in range(100000):
print(i)
Сценарий останавливается иногда и до й печатаются, иногда в течение цикла в конце, а иногда он не останавливается на всех. Вероятность остановки зависит от значений lakeNr
и trialNr
, хотя я не нашел полезной корреляции. Возможно, это связано с различными случайными числами, с которыми заполняется входная матрица, если ее размер изменяется. Ни в коем случае исключение составляет. Программа останавливается, как будто она завершена.
Я смог обнаружить функцию в своем расширении, которое должно нести ответственность за это поведение. Во-первых, я покажу вам свою функцию-обертку:
static PyObject *FlowCalc_flowCalc(PyObject *self, PyObject *args)
{
PyArrayObject *trials_array, *flows_array, *result;
/* Parse the input tuple */
if (!PyArg_ParseTuple(args, "OO", &trials_array, &flows_array)) {
PyErr_SetString(PyExc_ValueError,
"Exception");
return NULL;
}
pymatrix_to_CarrayptrsInt(trials_array);
return Py_BuildValue("i", 42);
Проблема должна лежать в функции pymatrix_to_CarrayptrsInt
:
int **pymatrix_to_CarrayptrsInt(PyArrayObject *arrayin) {
int **c, *a;
int i,n,m;
n=arrayin->dimensions[0];
m=arrayin->dimensions[1];
c=ptrvectorInt(n);
a=(int *) arrayin->data; /* pointer to arrayin data as int */
for (i=0; i<n; i++) {
c[i]=a+i*m; }
return c;
}
int **ptrvectorInt(long n) {
int **v;
v = (int**) malloc((size_t) (n * sizeof(int)));
if (!v) {
printf("In **ptrvectorInt. Allocation of memory for int array failed.");
exit(0); }
return v;
}
Этот метод является измененная перевыполнение pymatrix_to_CarrayptrsDouble
:
double **pymatrix_to_CarrayptrsDouble(PyArrayObject *arrayin) {
double **c, *a;
int i,n,m;
n=arrayin->dimensions[0];
m=arrayin->dimensions[1];
c=ptrvectorDouble(n);
a=(double *) arrayin->data; /* pointer to arrayin data as double */
for (i=0; i<n; i++) {
c[i]=a+i*m; }
return c;
}
double **ptrvectorDouble(long n) {
double **v;
v = (double**) malloc((size_t) (n * sizeof(double)));
if (!v) {
printf("In **ptrvectorDouble. Allocation of memory for double array failed.");
exit(0); }
return v;
}
Версия с двойной работает отлично и не вызывает никаких проблем. Я предполагаю, что проблема связана с управлением памятью, но я не уверен. Кто-нибудь есть идея, что проблема с версией int может быть?
A am using python 3.4 64bit с Windows 8 64bit (компилятор: Visual Studio 10).
Благодарим за помощь!
Вещь, которая поражает меня как нечетную, - вы не проверяете тип элементов массива. –
@ivan_pozdeev: Пока я знаю, что входные массивы имеют правильный тип. Как только я завершаю модуль расширения, я обязательно добавлю проверку типа. Я в основном скопировал код (версию для double) из http://wiki.scipy.org/Cookbook/C_Extensions/NumPy_arrays. Есть много вещей, которые я буду менять, чтобы подчеркнуть стиль. Однако я не думаю, что эти проблемы связаны с ошибкой. – Samufi