user2660761
user2660761

Reputation: 11

From numpy matrix to C array. Segmentation fault (memory corruption) on 64bit architecture

I'm trying to build up a python C extension in order to pass a numpy matrix to a C array. I was following the suggestions reported here:

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

but when Python tries to run the C line:

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

of the follow portion of code:

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;
}

I get a segmentation fault on my Linux 64 bit machine. The problem is that this code works perfectly on 32 bit machines (both Windows and Linux). Moreover sizeof(size_t) returns correctly 4 on 32bit machines and 8 on 64bit machines. I'm using Python 2.7.1 [EPD 7.0-2 (64-bit)] and GCC 4.1.2 on a Red Hat Linux 4.2.1-44 with kernel version 2.6.18.

I tried also with npy_intp and also Py_ssize_t instead of size_t but no positive effect.

Upvotes: 1

Views: 433

Answers (1)

alk
alk

Reputation: 70941

Here you want to allocate memory for pointers to float:

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

but you do allocated memory for floats themselfes. On a 32bit system pointers need 4 bytes, so this works.

On a 64bit system pointers need 8 byte, so you might like to change the above line to be:

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

or even more secure to

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

Btw: In C it is not needed to caste the result of malloc/calloc/realloc nor is it recommended. Even more it is dangerous to do so as it might hide awful mistakes.

Upvotes: 2

Related Questions