Reputation: 657
I have encountered a problem with passing two dimensional arrays to other function as parameter. It was not working when I tried as below.
#include <stdio.h>
int display(int **src) {
printf("%d", src[0][1]);
}
int main() {
int arr[2][2] = {{1,2}, {3,4}};
display(arr);
return 0;
}`
It raises segmentation fault error. So I changed the display function as below
int display(int src[][3]) {
printf("%d", src[0][1]);
}
I am not sure why first case raises error. Please help me to understand deeply about this case.
Upvotes: 0
Views: 909
Reputation: 41065
int display(int **src) {
printf("%d", src[0][1]);
}
you can not do that because the compiler doesn't know the dimensions (rows and columns), in other words: C doesn't use introspection.
Instead:
int display(int src[][2]) {
printf("%d", src[0][1]);
}
or if you prefer
int display(int (*src)[2]) {
printf("%d", src[0][1]);
}
Note that you don't need to specify the first dimension, C is able to calculate the position based on the offset: (sizeof(int) * cols)
Also, you promised to return
something from the function, if you don't want to return
a value use:
void display(int (*src)[2]) {
Finally, as pointed out by @Scheff in comments, your original array haves 2 columns, receiving 3 will break the indexing in the receiver.
Upvotes: 3
Reputation: 215360
Pointers are not arrays and arrays are not pointers. There is a common misunderstanding that type**
somehow has something to do with 2D arrays. It has not. It is not a 2D array and it cannot point at a 2D array.
There's a look-up table design pattern where you use int**
to point at an array of int*
items, where each int*
points at a chunk of dynamically allocated memory. By using int**
we can "emulate" the [x][y]
array syntax, so these look-up tables look like 2D arrays, but they are not, because the data is not allocated adjacently. More on that topic here: Correctly allocating multi-dimensional arrays.
The correct way to pass a 2D array to a function is:
void display(int src[2][2]) {
printf("%d", src[0][1]);
}
This does not pass the array by value, as one might think. Just like a regular 1D array, the parameter implicitly "decays" into a pointer to the first element, and the first element of a 2D array is a 1D array. So this is 100% equivalent to void display(int (*src)[2]);
. And if we modify src[i][j]
from inside the function, we therefore modify the original array allocated by the caller.
And because of this array decay, it actually doesn't matter what size we type for the outer-most (left) dimension. We can as well type void display(int src[][2]);
(which is actually an array of imcomplete type) and the result will be the same: a decay into an array pointer int (*)[2]
.
If standard C variable-length arrays are available, then you can also declare the function with variable dimensions:
void display (size_t x, size_t y, int src[x][y]);
Upvotes: 2