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]);