C扩展中的函数随机停止python程序的执行

C扩展中的函数随机停止python程序的执行,python,c,memory-management,random,python-c-extension,Python,C,Memory Management,Random,Python C Extension,我对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(shap

我对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)
脚本有时在打印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中:

使用double的版本工作正常,不会导致任何问题。我猜这个问题与内存管理有关,但我不确定。有人知道int版本的问题是什么吗

am使用Python3.4 64位和Windows8 64位编译器:VisualStudio10


谢谢你的帮助

我找到了避免问题的方法:为输出数组分配内存的函数ptrvectorInt不能正常工作。我把它换成了

int **ptrvectorInt(long dim1) {
   int **v;
   if (!(v = malloc(dim1 * sizeof(int*)))) {
      PyErr_SetString(PyExc_MemoryError,
              "In **ptrvectorInt. Allocation of memory for integer array failed.");
      exit(0); 
   }
   return v;
}

一切顺利。我仍然不完全知道错误的机制,即它为什么出现以及它为什么随机停止程序。但是,问题解决了。

让我感到奇怪的是,你没有检查数组元素的类型。@ivan_pozdeev:现在我知道输入数组的类型是正确的。一旦完成扩展模块,我肯定会添加一个类型检查。我基本上复制了double版本的代码。为了提升风格,我会做更多的改变。不过,我不认为这些问题与错误有关。
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 **ptrvectorInt(long dim1) {
   int **v;
   if (!(v = malloc(dim1 * sizeof(int*)))) {
      PyErr_SetString(PyExc_MemoryError,
              "In **ptrvectorInt. Allocation of memory for integer array failed.");
      exit(0); 
   }
   return v;
}