views:

118

answers:

3

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.

A: 

2D 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.

naivnomore
+9  A: 

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)).

Johannes Schaub - litb
Oh yeah, thanks. It is about the `sizeof(T)`.
Ashish
+1  A: 

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 ints).

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.

mathepic