The big problem is that p
and &x
are different types.
The pointer given by &x
is a pointer to the whole array x
, not to a single element, and its type is int (*)[3]
, not int *
.
If you want to get a pointer to the first element of x
then use &x[0]
, or plain x
(as that decays to &x[0]
).
And even while the types of &x
and &x[0]
are different, they both point to the same location (as your (invalid) printouts indicates). This can be seen if you attempt to visualize the array x
in memory:
+------+------+------+
| x[0] | x[1] | x[2] |
+------+------+------+
^
|
&x
|
&x[0]
As I already mentioned in a comment, to print pointers you need to use the %p
format specifier. Mismatching formatting specifier and argument type leads to undefined behavior.
What's more, the %p
format specifier is for void *
pointers, so you need to cast the pointers (unless they are already void *
of course):
printf("%p %p \n", (void *) p, (void *) x);