Why am I getting Segmentation fault dynamic matrix?

Asked

Viewed 176 times

3

They say not to cast on the return of function malloc, but this code there if the dimension of the matrix is above 4, it gives Segmentation fault from matriz[5][1] in the count:

int main(){

    int tamanho = 5;

    float **matriz = malloc(tamanho * sizeof(float));

    for(int i=0; i<tamanho; i++)
        *(matriz + i) = malloc(tamanho * sizeof(float));

    for(int i=0; i<tamanho; i++){
        for(int j=0; j<tamanho; j++){
            scanf("%f", &matriz[i][j]);
        }
    }
}

Now if I give cast, then it works well. But, why? If they say they can’t...

  • 3

    One thing I’m seeing is that in the first malloc you’re utilizing sizeof(float), when the right one would be sizeof(float*). If you’re compiling for 64bit it makes all the difference.

2 answers

6

Notice that line:

float **matriz = malloc(tamanho * sizeof(float));

whereas tamanho is 5 and sizeof(float) is 4, that would be:

float **matriz = malloc(20);

And then here, we have this:

for(int i=0; i<tamanho; i++)
    *(matriz + i) = malloc(tamanho * sizeof(float));

You use *(matriz + i), that is to add an integer with pointer, which is not a good idea. This then takes the value of the address and adds to it the value of i multiplied by the size of the type referenced by the pointer, which is float *. Whereas the pointer size is 8 bytes, this will access the positions, 0, 8, 16, 24 and 32. When accessing positions 24 and 32 (and half the area of 16), you will be writing in an unallocated memory area, which can give Segmentation fault.

The problem is that you allocated the matrix to the wrong size because it is a pointer matrix, not an array of floats. That is, instead:

float **matriz = malloc(tamanho * sizeof(float));

You should have put this (note the * the most):

float **matriz = malloc(tamanho * sizeof(float *));

And it makes all the difference since sizeof(float) is 4 while sizeof(float *) is 8.

And also, I recommend rewriting this:

    *(matriz + i) = malloc(tamanho * sizeof(float));

Thus:

    matriz[i] = malloc(tamanho * sizeof(float));

2

In short:

this line

float **matriz = malloc(tamanho * sizeof(float)); // BAD

it’s wrong, it should be like this:

float **matriz = malloc(tamanho * sizeof(float*)); // GOOD

One thing most beginners fail to understand is that there are no "matrices" in C, what appears to be an "array" is actually an array of pointers.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.