1

In the code below I set the variable var to 20, then the pointer ptr to the address of var. Then the pointer ptrptr to hold the memory address of the pointer ptr.

#include <stdio.h>

void pointers()
{
    int var = 20;
    int* ptr;
    ptr = &var;

    int *ptrptr = ptr;

    printf("Value at ptrptr[0] = %d \n", ptrptr[0]);
}

// Driver program
int main()
{
    pointers();
    return 0;
}

Output:

Value at ptrptr[0] = 20

Why does ptrptr[0] return the value stored by val, and not the memory address of the pointer ptr.

I thought that the indexing operator [] returns the value stored by that value.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
Dylan Dijk
  • 277
  • 1
  • 6
  • 2
    there is no `val` in the code – 463035818_is_not_an_ai Feb 08 '23 at 13:41
  • 6
    `ptrptr` and `ptr` are both of the same type and hold the same value - the address of `var`. If you want `ptrptr` to hold the address of `ptr` you need another level of indirection: `int **ptrptr = &ptr;`. – wohlstad Feb 08 '23 at 13:41
  • 1
    Just because you name something `ptrptr`, it doesn't become a pointer to pointer. I'll assume that `int *ptrptr` was just a typo, you meant `int **ptrptr` and we can therefore close this as 'simple typo'. – Lundin Feb 08 '23 at 13:47

5 Answers5

6

Here is an example which will, I hope, make it more clear what's going on.

#include <stdio.h>

int main()
{
    int var = 20;
    int *ptr = &var;
    int *ptr2 = ptr;

    printf("the value of the variable var is %d\n", var);
    printf("the address of the variable var is %p\n\n", &var);

    printf("the value of the pointer ptr is %p\n", ptr);
    printf("the value pointed to by ptr is %d\n", *ptr);
    printf("or, stated another way, it's %d\n\n", ptr[0]);

    printf("the value of the pointer ptr2 is %p\n", ptr2);
    printf("the value pointed to by ptr2 is %d\n", *ptr2);
}

On my machine this prints:

the value of the variable var is 20
the address of the variable var is 0x7ffeed56992c

the value of the pointer ptr is 0x7ffeed56992c
the value pointed to by ptr is 20
or, stated another way, it's 20

the value of the pointer ptr2 is 0x7ffeed56992c
the value pointed to by ptr2 is 20

Since ptr and ptr2 have the same type (int *), and since they hold the same pointer value (since we said ptr2 = ptr), they behave the same.

And because of the "correspondence between arrays and pointers" in C, *ptr is identical to ptr[0]. Both expressions yield the value pointed to by ptr.

If your intention with ptrptr was to have it be a pointer to a pointer, here's an illustration of that wrinkle. Since ptrptr is a two-level pointer, its pointed-to value is actually another pointer, so you have to be really careful thinking about it.

int **ptrptr = &ptr;
printf("the value of the pointer ptrptr is %p\n", ptrptr);
printf("the value pointed to by ptrptr is %p\n", *ptrptr);
printf("and the value pointed to by that pointer is %d\n", **ptrptr);

This additionally prints:

the value of the pointer ptrptr is 0x7ffeed569920
the value pointed to by ptrptr is 0x7ffeed56992c
and the value pointed to by that pointer is 20
Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • Thanks for your answer, when you say the "correspondence between arrays and pointers" what is meant by this. Are they any resources that explain this further, I am a beginner. – Dylan Dijk Feb 08 '23 at 14:16
  • 1
    @DylanDijk The "correspondence between arrays and pointers" is a [new term I devised](https://stackoverflow.com/questions/48868367#48887033) which has not really caught on yet. The older wording was "equivalence between arrays and pointers", but that term is deprecated now. Another term is "array to pointer decay". – Steve Summit Feb 08 '23 at 16:51
  • 1
    The two main parts of this principle are that (a) when you mention an array in an expression, as if to take its value, what you get (the value you get) is actually a pointer to the array's first element, as if you had written `&a[0]`, and (b) the array-subscripting operator `a[i]` is defined as (is precisely equivalent to) `*(a + i)`. – Steve Summit Feb 08 '23 at 16:54
  • 1
    Any proper textbook or tutorial or other instructional material on C should explain this, usually in a section called "arrays and pointers". (Some, though, explain it better than others, and unfortunately, some of the explanations out there are really bad. In particular, if you come across an "explanation" that says something like "an array is a constant pointer to its first element", stop reading and find a better tutorial.) – Steve Summit Feb 08 '23 at 16:55
4

By definition *(ptr + n) === ptr[n]

Why does ptrptr[0] return the value stored by val, and not the memory address of the pointer ptr.

I thought that the indexing operator [] returns the value stored by that value.

no ptr[x] dereferences the pointer.

int x = 5;
int *ptr = &x;
int *ptrptr = ptr; //this assigns reference stored in ptr to ptrptr. Now they store the same reference.

printf("Dereferencing pointer - %d\n", ptr[0]);
printf("Reference stored in the pointer - %p\n", (void *)ptr);
printf("Reference of the pointer (its address) - %p\n", (void *)&ptr);

Judging from the name of your second pointer you probably wanted pointer to pointer

int x = 5;
int *ptr = &x;
int **ptrptr = &ptr; //poiter to pointer

printf("Dereferencing pointer to pointer - reference of x %p\n", (void *)ptrptr[0]);
printf("Reference stored in the pointer to pointer - reference of ptr%p\n", (void *)ptrptr);
printf("Reference of the pointer (its address) - %p\n", (void *)&ptrptr);
0___________
  • 60,014
  • 4
  • 34
  • 74
3

This

ptrptr[0]

is the same as (because ptrptr and ptr are same type and have same value):

ptr[0]

is the same as (because a[b] == *(a+b)):

*ptr

is the same as var, because ptr points to var, and *ptr is dereferencing the pointer.

The value of var is 20.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
2

ptrptr has the same type as ptr, a pointer to an int. So when you do int *ptrptr = ptr;, now ptrptr and ptr point to the same address (that's why it compiles as well). Also ptrptr[0] is the same as to *ptrptr

You have to define ptrptr to be a pointer to a pointer of an int:

int **ptrptr = &ptr;
printf("Value at ptrptr[0] = %d \n", *ptrptr[0]);

if you wanted ptrptr to point to ptr

Link to Compiler Explorer.

1

You never set ptrptr to hold the memory address of ptr but to the value of ptr itself. Below is an image for illustration. First ptr is assigned the address of var and then ptrptr is assigned the value of ptr, so it also points to var.

equal pointers

To make ptrptr point to ptr you need to declare it as

int **ptrptr = &ptr;

pointer to pointer

August Karlstrom
  • 10,773
  • 7
  • 38
  • 60