从numpy矩阵到C数组。 64位架构上的分段错误(内存损坏)

时间:2013-08-07 13:25:44

标签: c numpy

我正在尝试构建一个python C扩展,以便将numpy矩阵传递给C数组。我按照这里报告的建议:

http://wiki.scipy.org/Cookbook/C_Extensions/NumPy_arrays

但是当Python尝试运行C行时:

v=(float **)malloc((size_t) (n*sizeof(float)));

以下代码:

float **_ptrvector(long n) { 
    float **v;
    v=(float **)malloc((size_t) (n*sizeof(float)));
    if (!v)   {
        printf("In **ptrvector. Allocation of memory for array failed.");
        exit(0); }
    return v;
}

float **pymatrix_to_carray(PyArrayObject *arrayin)  {
    float **c, *a;
    int i,n,m;

    n = PyArray_DIM(arrayin, 0);
    m = PyArray_DIM(arrayin, 1);
    c=_ptrvector(n);
    a = (float*) PyArray_DATA(arrayin);
    for ( i=0; i<n; i++)  {
        c[i]=a+i*m;  }  
    return c;
}

我的Linux 64位计算机上出现了分段错误。问题是这个代码在32位机器(Windows和Linux)上运行良好。此外,sizeof(size_t)在32位机器上正确返回4,在64位机器上返回8。我在内核版本为2.6.18的Red Hat Linux 4.2.1-44上使用Python 2.7.1 [EPD 7.0-2(64位)]和GCC 4.1.2。

我还尝试使用npy_intp和Py_ssize_t而不是size_t但没有正面效果。

1 个答案:

答案 0 :(得分:2)

在这里,您要为指向float的指针分配内存:

float **v;
v=(float **)malloc((size_t) (n*sizeof(float)));

但你为float他们自己分配了内存。在32位系统上,指针需要4个字节,因此可行。

在64位系统上,指针需要8个字节,因此您可能希望将以上行更改为:

float ** v = malloc(n * sizeof(float*));

甚至更安全

float ** v = malloc(n * sizeof(*v));

顺便说一句:在C中,不需要结算malloc/calloc/realloc的结果,也不建议这样做。这样做更危险,因为它可能隐藏可怕的错误。