0

I am learning C and I tried to allocate memory for a 2D array (the dimensions of the array I get them from the user), but I get a segmentation fault after I try to init it. My code is this:

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

int main()
{
   printf("give the dimensions!\n");
   int row,col,i,j; 
   int **myArray;

   printf("\nrows = ");
   scanf("%d", &row);
   printf("columns = ");
   scanf("%d", &col);
   myArray = malloc(row*sizeof(*myArray) + col*sizeof(**myArray));

   printf("Init the array: \n");
   for (i = 0; i < row; i++)
   {
       for (j = 0; j <col ; j++)
       {
           scanf("%d", &myArray[i][j]);
       }
   }

   return 0;
}

If I change the array as myArray[2][2] and omit the malloc statement it works fine..

yaylitzis
  • 5,354
  • 17
  • 62
  • 107

3 Answers3

5

There's no way for C to know how your indexing is supposed to work: there's no information that associates the number of columns (col) with myArray. When you do myArray[i][j] with myArray declared as int * *, C will first evalutate myArray[i], i.e. read the i:th value of myArray as if it were an integer pointer, which it isn't in your case. It will then index j from that invalid value, likely generating the segmentation fault (at least causing undefined behavior).

When doing it manually like that, you have two choices:

  • Make it "jagged", where each row has its own pointer to that row's elements. This is what @bgamlath suggests in his answer.
  • Do the indexing yourself, by replacing myArray[i][i] with myArray[i * cols + j].

The latter uses less memory and (way) less memorhy allocations, which is nice. Of course the indexing can be a bit awkward.

Community
  • 1
  • 1
unwind
  • 391,730
  • 64
  • 469
  • 606
2

Try doing it like this.

  table = malloc(row*sizeof(int *));
  for(i = 0; i<row; i++)
    table[i] = malloc(col * sizeof(int));
Buddhima Gamlath
  • 2,318
  • 1
  • 16
  • 26
  • yeah, i just saw an another question here similar to mine http://stackoverflow.com/questions/19059151/segmentation-fault-on-initializing-a-2d-array?rq=1 thx!!! – yaylitzis Dec 19 '13 at 08:09
  • That's not a 2D array, it is a pointer-based lookup table. 2D arrays are allocated in adjacent memory. [This is how you allocate a 2D array](http://stackoverflow.com/questions/12462615/how-do-i-correctly-set-up-access-and-free-a-multidimensional-array-in-c). – Lundin Dec 19 '13 at 08:32
0

You can allocate dynamic arrays like this. No malloc necessary.

{ 
  printf("rows = ");
  scanf("%d", &rows);
  printf("columns = ");
  scanf("%d", &cols);

  int my_array[rows][cols];
}

To zero the new array:

  memset(my_array, 0, rows*cols*sizeof(int));
Darren Stone
  • 2,008
  • 13
  • 16
  • 1
    only since C99, and provided the input isn't too large and causes the stack to overflow – Elias Van Ootegem Dec 19 '13 at 08:43
  • Absolutely. Anyone not working with C99 or beyond needs to stick with `malloc` and `free`. Since @Nat95 tells us he's a beginner, I am guiding him toward VLAs for two reasons: 1) notational convenience, particularly with multidimensional arrays as he is looking for, and 2) freedom from endless C beginner errors surrounding `malloc` and `free`. – Darren Stone Dec 19 '13 at 08:53