what is the output and why the pointer in function does not affect the code?

Viewed 191

why the op is 20 ?? not 10 ? I think the op should be 10 but I don't know what happened? can you please explain it step by step

void fun(int *ptr)
{
    int q=10;
    ptr=&q;
}

int main()
{
    int r=20;
    int *p=&r;
    fun(p);
    printf("%d",*p);
    return 0;
}
3 Answers
  • Values of function arguments are copies of what is passed from caller. Modifying in callee will not affect caller's local variables.
  • Non-static local variables will vanish on exiting its scope. Therefore, you must not dereference pointers to them after that.

To obtain 10, your code should be:

#include <stdio.h>

void fun(int **ptr) /* pass a pointer to modify caller's local variable */
{static int q=10; /* add static to prevent it from vanishing */
*ptr=&q; /* dereference the pointer */
}

int main()
{int r=20;
int *p=&r;
fun(&p); /* pass the pointer */
printf("%d",*p);
return 0;
}

This is p and r (addresses are for instance based)

 ----------------      ----------------      ----------------
 | r         20 |      | p       1234 |      | q         10 | 
 ----------------      ----------------      ----------------
 ^                     ^                     ^
 |_ Address of r       |_ Address of p       |_ Address of q
    = 1234                = 9876                = 12121

To fun(),

void fun(int *ptr) {
   int q = 10;
   ptr = &q;
}

you provide p as ptr (ie 1234), then set ptr to the address of q

fun:  ptr = 12121

then fun ends, and ptr dies with it, the memory didn't change for r

To change something you have to pass the address of that thing. Even if it is a pointer.

Giving the address of p to fun

fun( &p );

and changing fun() to accept a pointer to pointer

void fun(int **ptr) {  // <== pointer to pointer
   int q = 10;
   *ptr = &q;          // <== change r indirectly
}

here, ptr has the address of the pointer p, ie 9876

*ptr = &q; // changes the value of `r`

It´s basically because of two reasons:

  1. p in main() and ptr in fun() are two different pointers, and
  2. You pass p by value, not by reference.

At the function call:

fun(p);

you just pass p by value; Means it passes the address of r (what is actually the value of p) to ptr.

With ptr = &q; in fun() you just assign the address of q to ptr, but not to p.

Therefore, the output of dereferencing p at:

printf("%d",*p);

is of course 20, as p still point to r -> the value of p didn´t changed.


If you instead pass p by reference and declare ptr as pointer to pointer (**), plus qualify q with static qualifier (because function-local automatic variables will be destroyed after the function is executed once):

void fun(int **ptr)            // ptr is declared as pointer to pointer to int.
{
    static int q = 10;         // q is static -> It won´t get destroyed after returning from `fun()`.
    *ptr = &q;                 // dereferencing ptr to assign the address of q to p.
}

int main()
{
    int r = 20;
    int *p = &r;
    fun(&p);                   // Notice the `&` to gain the address of `p`, not `r`.
    printf("%d",*p);
    return 0;
}

The output would be 10 as we actually assigned the address of q to p.

As a side note: It is considered as bad programming style to refer to static-qualified function-local variables from a caller. I just showed this to you for the educational purpose and to show the difference to your provided code.

Try to assign an object pointed to in the caller, here f.e. r, by a passed pointer inside of the called function, here ptr, with the actual value of the object in the called function, here q.

Related