Я относительно новичок в расширениях C для Python. Я написал расширение, которое показывает поведение, которое мне кажется странным. Когда я запускаю скрипт 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)
Сценарий иногда останавливается до того, как x будет напечатан, иногда в конце цикла, а иногда вообще не останавливается. Вероятность стопа зависит от значений 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?
Я использую python 3.4 64bit с Windows 8 64bit (компилятор: Visual Studio 10).
Спасибо за вашу помощь!