In C, when we access a[i][j]
using pointers why do we need the second *
in *(*(a + i) + j)
? Using printf()
I see a + i
and *(a + i)
print the same value.
views:
118answers:
32D arrays are like array of arrays. *(a+i) gives you the address of the one dimensional array that is at location i from the start address. Now you need the element at location j in this array. Hence you add j to it & then de-reference using * to access that element.
a + i
is a pointer to the i
'th subarray. If you dereference it, you get an lvalue to the i
'th subarray, which decays to a pointer to that array's first element. The address of an array's first element and that of its array is the same.
The dereference is needed to make + j
calculate with the correct element byte-width. If you would not dereference, then instead of getting T*
you would get a T(*)[J]
pointer that you add j
to, which together with i
advances into memory pointing to (a + i + j)
instead (advancing by sizeof(T[J])
instead of sizeof(T)
).
Okay, this requires a bit of pointer theory.
Lets assume we have
int** a = malloc(sizeof(int*) * 10);
int** p;
for(p = a; p < a + 10; p++) {
*p = malloc(sizeof(int) * 15);
}
This creates a 10 by 15 "array" implemented using pointers. Notice how each elements contained in the block of memory pointed to by a
is of type int*
(because we are mallocing a block of 15 int
s).
Heres an incomplete diagram:
a
|
1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 8 - 9 - 10
| |
| 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15
|
1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15
So the main pointer is a pointer to a block that contains a bunch of pointers. So you end up dereferencing to get the inner pointer, you add to get another pointer, and you dereference again.