从numpy矩阵到C数组。64位体系结构上的分段故障(内存损坏)

从numpy矩阵到C数组。64位体系结构上的分段故障(内存损坏),c,numpy,C,Numpy,我试图构建一个PythonC扩展,以便将numpy矩阵传递给C数组。我遵循此处报告的建议: 但是当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

我试图构建一个PythonC扩展,以便将numpy矩阵传递给C数组。我遵循此处报告的建议:

但是当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;
}
float**ptrvector(长n){
浮动**v;
v=(浮动**)malloc((大小t)(n*sizeof(浮动));
如果(!v){
printf(“In**ptrvector.数组内存分配失败”);
退出(0);}
返回v;
}
浮点**pymatrix_到_carray(PyArrayObject*arrayin){
浮动**c、*a;
int i,n,m;
n=PyArray_DIM(arrayin,0);
m=PyArray_DIM(arrayin,1);
c=_ptrvector(n);
a=(浮点*)PyArray_数据(arrayin);

对于(i=0;i,这里您要为指向
float
的指针分配内存:

float **v;
v=(float **)malloc((size_t) (n*sizeof(float)));
但您确实为
float
s本身分配了内存。在32位系统上,指针需要4个字节,所以这是可行的

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

float ** v = malloc(n * sizeof(float*));
甚至更安全

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


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

如果你不是内核、libc或编译器黑客,你应该使用尾随下划线而不是前面的下划线来标记私有符号。numpy数组不保证是安全的内存中连续。我认为已经有了一个numpy C-Api函数来实现这一点。这一点是正确的;但是OP说崩溃发生在malloc;您指出使用
v
指向的空间将很快导致崩溃。对此有何想法?@Floris:根据我的经验
malloc()
只有在调用内存管理(MM)之前,内存管理(MM)以任何方式损坏时才会崩溃,最可能的情况是写入未分配的内存,并破坏/损坏MM的内部数据结构。想象一下OP的代码在一个循环中:第一次迭代会损坏MM,第二次迭代对
malloc()的调用
然后很容易使应用程序崩溃。但是,我强烈建议修复我的答案中指出的问题并重新测试。这是有道理的-真正的问题可能发生在其他地方(出于相同的原因),或在前面的代码中;当堆损坏时再次调用malloc时会发生崩溃。这很有意义。同意这是代码中一个严重的致命缺陷。我检查了,现在由于alk的建议,一切都正常了。