arrayscpointerspointer-arithmeticconceptual

Understanding static/dynamic array access with pointer arithmetic in C


I'm trying to understand how pointer arithmetic works in C. Say if I have two arrays, one static and the other dynamic like so,

int a[10];
int * b = malloc(sizeof(int) * 10); 

And lets assume each array has been initialized so that they both store numbers from 0 to 9 in order (well in the case for b, it stores the address to an array of numbers from 0 to 9 in order).

If we want to access the value 9 in array a using pointer arithmetic we can simply write *(a + 9). Similarly if we want to access the value 9 in array b, we can simply write *(b + 9).

However what confuses it me is how the computer is able to know when to dereference a variable. With the case for a, the computer treats the name as an address of the array a. However with b, it seems that the computer reads the address of b and also dereferences it additionally in order to get the base address of the array pointed by b.

Could someone please explain?

(Edit: specifically my confusion is related to how the names of both arrays are treated by the computer. For *(a + 9), the name a is read by the computer as an address of array a itself and added to (9 * 4). While for *(b + 9), b is instead read as the address stored in variable b.)


Solution

  • With the case for a, the computer treats the name as an address of the array a. However with b, it seems that the computer reads the address of b and also dereferences it additionally in order to get the base address of the array pointed by b.

    Not exactly. An array variable, when used in a expression, will decay into a pointer to its first member in most cases. That is what happens with a. In contrast, b is a pointer which contains the address of the first member of an array. No dereference happens until the * operator is applied.

    In the case of *(a + 9) (which is exactly equivalent to a[9]), a first decays to a pointer whose value is the address of the first member of the array, i.e. the element with index 0. Then the addition applied to this pointer value results in a pointer to the member with index 9, then the dereference operator accesses that member.

    Similarly in the case of *(b + 9) (which is exactly equivalent to b[9]), the value of b is the address first member of the dynamically allocated array, i.e. the element with index 0. Then the addition applied to this pointer value results in a pointer to the member with index 9, then the dereference operator accesses that member.