0
int main(){

    int right[2][3] = {
    {1,4,6}, {2,7,5}
    }

    ....


    calc(right);
}

int calc(int ** right){
    printf("%i", right[0][0]);
}

I calc function that calculate some numbers based on a matrix, but I dont' know why i get seg fault when I access the variable right within the calc function. does any body know the solution?

edit: right now that is all it's doing at calc function. I have some calc stuff but it's all commented out trying to figure out how to access this variable.

Anatoli
  • 922
  • 2
  • 11
  • 25
  • 4
    You need to post the code for `calc` function for any body to help. – Naveen Sep 08 '10 at 07:37
  • You probably try to access the whole array but you only initialize right[0] and [1] IMO. – InsertNickHere Sep 08 '10 at 07:39
  • can you paste the code of calc as well?and why are you using int ** right?? – Anil Vishnoi Sep 08 '10 at 07:39
  • 3
    possible duplicate of *many* questions, including [Passing arrays and matrices to functions as pointers and pointers to pointers in C](http://stackoverflow.com/questions/546860/passing-arrays-and-matrices-to-functions-as-pointers-and-pointers-to-pointers-in) – Binary Worrier Sep 08 '10 at 07:46

2 Answers2

7

Two-dimensional arrays in C don't work the way you think they do. (Don't worry, you're not alone -- this is a common misconception.)

The assumption implicit in the code is that right is an array of int * pointers, each of which points to an array of int. It could be done this way -- and, confusingly, the syntax for accessing such an array would be the same, which is probably what causes this misconception.

What C actually does is to make right an array of 12 ints, layed out contiguously in memory. An array access like this

a=right[i][j];

is effectively equivalent to this:

int *right_one_dimensional=(int *)right;
a=right[i*3 + j];

To pass your array to the calc function, you need to do this:

int calc(int *right, size_t d){
    // For example
    a=right[i*d + j];
}

and then call it like this:

int right[2][3] = {
    {1,4,6}, {2,7,5}
};

calc(&right[0][0], 3);

Edit: For more background on this, the question linked to in Binary Worrier's comment is definitely worth looking at.

Martin B
  • 23,670
  • 6
  • 53
  • 72
  • 2
    You could also specify calc as `int calc(int right[][3])` and call it by simple doing `calc(right);` – nos Sep 08 '10 at 07:52
2

Although a one-dimensional array is automatically converted to a pointer, the same does not hold for a multi-dimensional array and multi-level pointers.

If you change the order of the calc and main functions (or if you provide a prototype for calc before main), you will get a complaint from the compiler that it can convert right to the type int**.

The reason is that right is declared as an "array of 4 arrays of 3 int". This can be automatically converted to "pointer to array of 3 int" (int (*)[3]), but that is where the conversions stop. calc on the other hand expects a "pointer to a pointer to int", which is a completely different beast from a "pointer to array of 3 int".

There are two possible solutions:

  1. Change calc to accept a pointer to an array (or array of arrays):
   int calc(int right[][3])
  1. Change right to be a pointer to a pointer:
    int temp_array[4][3];
    int* temp_array2[4] = { temp_array[0], temp_array[1], temp_array[2], temp_array[3] };
    int** right = temp_array2;
Bart van Ingen Schenau
  • 15,488
  • 4
  • 32
  • 41