Akash
Akash

Reputation: 71

How does de-referencing work for pointer to an array?

Pointer to array of elements when dereferenced return an address. Since it is holding the address of the first element of the array, dereferencing it should return a value.

int arr[] = { 3, 5, 6, 7, 9 }; 
int *p = arr; 
int (*ptr)[5] = &arr;     
printf("p = %p, ptr = %p\n", p, ptr); 
printf("*p = %d, *ptr = %p\n", *p, *ptr);

Output:

p = 0x7fff6ea72d10, ptr = 0x7fff6ea72d10

*p = 3, *ptr = 0x7fff6ea72d10

Why does *ptr return the base address of the array, shouldn't it return the value at that address??

Upvotes: 1

Views: 624

Answers (5)

Serge
Serge

Reputation: 12354

The behavior you see is a result of 'c' interpreting arr as a pointer to the memory location of the first element. Pointer to the array &arr will be an address of the array itself in memory, which is also the address of its first element. As a result arr and &arr yield the same values. Try this:

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

Thought the values are the same, types are different. arr is a variable, whether &arr is a pointer to the variable.

ptr reflects the same picture. Its value ptr = &arr makes it a pointer to an array. It contains the address of the array. *ptr returns the array itself, which in 'c' interpretation is the address of the first element of the array. As a result values for ptr and *ptr are the same as for &arr and arr.

Hope it makes it clearer (not murkier) :-)

Upvotes: -1

The question was

"Why does *ptr return the base address of the array, shouldn't it return the value at that address?"

It does return the value at that address, which is the array arr.

Think about a queue of people: you can point to the first person and say "that person over there" or you can point to the same person and say "that queue over there". There are 2 things at the same location: a person and a queue. Same thing happens with arrays: person * for that "person over there" and person (*)[42] "for that queue of 42 people". If you dereference a pointer to queue, you get a queue. If you take the first from the queue you get a person.


But then the array itself will decay to address to the first element when it is given as an argument to printf. Thus here,

int arr[] = { 3, 5, 6, 7, 9 }; 
int (*ptr)[5] = &arr;     

// undefined behaviour really, all pointers should be cast to void *
printf("%p %p %p %p", *ptr, &ptr[0], arr, &arr[0]);

all these 4 expressions will result in pointer to int, and the value is the address of the first element in the array (the address of 3 in arr).

Upvotes: 2

Max
Max

Reputation: 22335

Here is a simple, less technical explanation.

How are you setting p? = arr;

How are you setting ptr? = &arr;

Your question really has nothing to do with arrays at all. arr could be literally any type and the answer would be the same: & gets the address of arr, so whatever arr is, ptr is storing its address while p is storing arr itself.

If you do *ptr, you will dereference that address and thus get a value equal to p.

int arr = 3;
// clearly these are different!
int p = arr;
int* ptr = &arr;

Similarly

int x = 3;
int* arr = &x;
// clearly these are different!
int* p = arr;
int** ptr = &arr;
// so of course they dereference differently
printf("*p = %d, *ptr = %p\n", *p, *ptr);

Upvotes: 0

jsarbour
jsarbour

Reputation: 1148

Arrays are pointers. Arrays are not pointers, see the comments below

A pointer to an array is a pointer, pointing at a pointer. Try de-referencing twice over, that should yeild a value.

Upvotes: -3

David C. Rankin
David C. Rankin

Reputation: 84569

Why does *ptr return the base address of the array, shouldn't it return the value at that address??

(p3) Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary '&' operator, or is a string literal used to initialize an array, an expression that has type "array of type" is converted to an expression with type "pointer to type" that points to the initial element of the array object and is not an lvalue. C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3)

int (*ptr)[5] = &arr;

ptr is a pointer-to-array of int [5]. When you dereference ptr you get array of int[5]. How is an array of int[5] accessed?

Rule 6.3.2.1 provides the answer:

"array of type" is converted to an expression with type "pointer to type" that points to the initial element of the array object...

Now if you dereference again (e.g. **ptr), then you get the value of the 1st element.

Upvotes: 7

Related Questions