Unable to dereference double pointer in c

xinix Source

The output of this code is 20 20 10. The first 20 is easy to understand. But I am unable to understand how function change1 and change2 are accessing the variable b.

#include<stdio.h>
int a = 5, b = 10;
void change1(int *p);
void change2(int **pp);
main( )
{
    int x=20, *ptr=&x;
    printf("%d  ",*ptr);
    change1(ptr);
    printf("%d  ",*ptr);
    change2(&ptr);
    printf("%d\n",*ptr);
}
void change1(int *p)
{
    p = &a;
}
void change2(int **pp)
{
    *pp = &b;
}
cdereferencedouble-pointer

Answers

answered 3 months ago R Sahu #1

But I am unable to understand how function change1 and change2 are accessing the variable b.

There is a misunderstanding of what change1 does.

It changes where p points to but that change is local to the function. It does not change where ptr points to in main since the pointer is passed by value. change1 does not have any code that accesses the variable b. It's not clear to me whey you think it does.

In change2, you are changing where the pointer points to, to b. The change affects where ptr points to in main since you are passing the address of ptr to change2 and you are changing where that dereferenced pointer points to.

answered 3 months ago wookiekim #2

void change1(int *p)
{
    p = &a;
}

The variable p is assigned with the address of a, but this is only valid within the function. p acts as a local variable within the function change1. After this function terminates, the pointer ptr would still be pointing at x(=20). This is the reason behind the second 20.

void change2(int **pp)
{
    *pp = &b;
} 

But this, is one of the correct ways to make changes to a pointer variable within the function so that it would still be valid outside. pp acts as a pointer pointing to the original ptr variable. As a result, ptr will end up pointing at b(=10) after change 2 terminates. This is the reason behind your third 10.

answered 3 months ago Daniele Cappuccio #3

When you invoke change1() function, you're passing the pointer ptr as an argument. Let's suppose ptr = 0xcafebabe, and obviously *ptr = 20.

Under the hood, you're writing the value 0xcafebabe on the stack, and the change1() function will only overwrite this value with &a on the stack frame corresponding to this function.

In the second case, you're passing a pointer to ptr as an argument. Let's suppose this pointer new_ptr has a value of 0xdeadbeef.
In this case, *new_ptr = 0xcafebabe and you overwrite 0xcafebabe with &b (hence you are changing where the pointer is pointing.

answered 3 months ago jp2g #4

In change1, p is a pointer to int that is passed by value. Assigning a value to p in change1 therefore has no effect because p is local to change1. This is the reason for the 2nd 20.

In change2, pp is a pointer to a pointer to int. It too is passed by value, but this time dereferencing pp (*pp) gives access to the location of the pointer (ptr), and it is into this location that the address of b (&b) is stored.

comments powered by Disqus