I'm studying multy-pointers and I watched this video, where explains that, if we want to access the value of a 2D array, we use double indirection like this:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv){
int a[2][2] = {{1,2},{3,4}};
int** p = &a[0][0];
printf("%d", **p);
return 0;
}
But I get a segmentation fault
. If I do instead a single indirection:
int a[2][2] = {{1,2},{3,4}};
int** p = &a[0][0];
printf("%d", *p);
I get the correct value a[0][0] = 1
. Now, if I use pointer arithmetic in the single inderection,
printf("%d", *(p+1));
I get a[1][0] = 3
, which makes sense because if I printf("%d", sizeof(p))
, I get 8 bytes.
Now my question is, How do I get a[0][1]
and a[1][1]
using pointer arithmetic?
int** p = &a[0][0];
This is wrong. The type of a[0][0]
is int
; therefore, the type of &a[0][0]
is int *
, not int **
, and that line should be
int *p = &a[0][0];
So,
*p == a[0][0] == 1
*(p + 1) == a[0][1] == 2
*(p + 2) == a[1][0] == 3
*(p + 3) == a[1][1] == 4
Remember that unless it is the operand of the sizeof
, _Alignof
, or unary &
operators, an array expression will "decay" to a pointer expression and the value of the pointer will be the address of the first element of the array:
Expression Type "Decays" to Equivalent expression
---------- ---- ----------- -----------------------
a int [2][2] int (*)[2] &a[0]
*a int [2] int * a[0]
a[i] int [2] int * &a[i][0]
*a[i] int n/a a[i][0]
&a int (*)[2][2] n/a n/a
&a[i] int (*)[2] n/a n/a
&a[i][j] int * n/a n/a
This is important - a 2D array expression decays to a pointer to an array, not a pointer to a pointer.
If
a[i] == *(a + i)
then
a[i][j] == *(*(a + i) + j)
So if you declare a pointer
int (*p)[2] = a;
then
p == &a[0] // int (*)[2] == int (*)[2]
*p == a[0] == &a[0][0] // int * == int *
*(p + 1) == a[1] == &a[1][0] // int * == int *
*(*(p + 1)) == a[1][0]