Home > OS >  Printf function %p behave differently when it is given an array compared to a pointer
Printf function %p behave differently when it is given an array compared to a pointer

Time:09-03

In the first printf the output is the address of arr and I was expecting this. However in the second one it prints the same address. Isn't it supposed to print the "value" pointed to by arr ( which is the address 0 ) ?

 char * arr[2];
 char ** p;


 int main(){
 
  p = arr;

  printf("%p\n",&arr);
  printf("%p\n",arr);

  printf("%p\n",&p);
  printf("%p\n",p);

  /* OUTPUT 
  0x10aa71010
  0x10aa71010
  0x10aa71020
  0x10aa71010
  */

 }

CodePudding user response:

The variable p is a pointer. It points to the first element of arr. Applying the pointer-to operator & (also known as the address-of operator) to p will create a pointer to the variable p.

Drawing it, it would be something like

 ----        ---        -------- 
| &p | ---> | p | ---> | arr[0] |
 ----        ---        -------- 

With arrays it's really the same, applying the pointer-to operator to an array gives you a pointer to the array. But the location of the array is the same as the location of the first element of the array.

Drawing it would be something like this:

 -------- -------- 
| arr[0] | arr[1] |
 -------- -------- 
^
|
&arr[0] (pointer to the first element, what plain arr decays to)
|
&arr    (pointer to the array itself)

From these "drawings" it should hopefully be easier to understand why p and &p would be different, as well as why arr and &arr would be the same.

Very important note: While &arr and &arr[0] point to the same location, the two pointers have different type and are therefore semantically different. Doing pointer arithmetic with the two pointers will not give the same result.

For your example, the type of &arr will be char *(*)[2], while the type of &arr[0] will be char **.


On a technical and kind of nitpicking note, the printf format %p is really for printing void * pointers. And the pointers you pass to printf will have different types.

Mismatching format specifier and argument type leads to undefined behavior. So to be fully correct you need to cast all pointers to void *.

CodePudding user response:

After this assignment

p = arr;

the pointer p points to the first element of the array arr. Note that arrays used in expressions with rare exceptions are implicitly converted to pointers to their first elements.

Thus the address of the first element of the array arr is equal to the address of the array itself.

So this call of printf

printf("%p\n",p);

outputs the address of the first element of the array stored on the pointer p after its assignment.

On the other hand the array arr and the pointer p occupy different extents of memory.

char * arr[2];
char ** p;

And this call of printf

printf("%p\n",&p);

outputs the address of the pointer p itself.

  • Related