1

I've tried to create a matrix in C and have some input value, but I don't know why it throws me a "segmentation error". This is my code:

#include <stdio.h> 
#include <stdlib.h>

int main() {
    int i;
    int j;
    int **a;
    a = malloc(5 * sizeof(int));
    for (i = 0; i < 5; i++) {
      a[i] = malloc(4 * sizeof(int));
    }
    for (i = 0; i < 5; i++) {
      for (j = 0; j < 4; j++) {
        scanf("%d", (a[i][j]));
      }
    }
    return 0;
}
diogo
  • 3,769
  • 1
  • 24
  • 30
fenigo69
  • 53
  • 1
  • 8

2 Answers2

2

Given the answer by @Bathsheba, this is what your code should look like:

#include <stdio.h>
#include <stdlib.h>

int main (void)
{
  int (*a)[4] = malloc( sizeof(int[5][4]) );

  for(int i=0;i<5;i++)
  {
    for(int j=0;j<4;j++)
    {
      scanf("%d", &a[i][j]);
    }
  }

  free(a);
  return 0;
}
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Upvoted. This is the "ace" answer, but I don't have enough confidence to use it, especially when you have to consider decay to pointers. – Bathsheba Dec 05 '16 at 11:45
  • @Bathsheba Array pointers don't decay. When passing this array pointer to a function, you would simply declare the function as `void func (size_t x, size_t y, int array[x][y])`. Where `int array[x][y]` will get adjusted by the compiler ("decay") into a pointer to the first element: `int (*array)[y]`. Which is exactly what we have in the caller. – Lundin Dec 05 '16 at 12:01
  • That's helpful. In fact much of this is above my pay grade. Do feel free to take facets from my answer and incorporate it into this one. – Bathsheba Dec 05 '16 at 12:03
  • 1
    @Bathsheba Nah, your answer is fine, I just couldn't stand by watching you die inside :) – Lundin Dec 05 '16 at 12:08
0
  1. Your allocation for a should be

a=malloc(5*sizeof(int*));

Note well the pointer type in the sizof. On some systems (Windows desktops in the early 2000s) an int just happened to be the same size as an int*, but you must not assume that.

  1. scanf takes a pointer as the parameter: the clearest way to write this is scanf("%d", &a[i][j]);

  2. Don't forget to free the memory once you're all done.

Finally, I die a little inside every time I see a matrix modelled like this. Granted, it allows you to use the [][] notation, but normally it's better to model it as a contiguous memory block and use the idiom i * columns + j to access the element at (i, j).

Bathsheba
  • 231,907
  • 34
  • 361
  • 483