1
#include<stdio.h>

void foo(int*);
int main()
{
    int i = 97, *p = &i;
    foo(p);
    printf("%d ", *p);
    getch();
}

void foo(int *p)
{
    int j = 2;
    p = &j;
    printf("%d ", *p);
}

Output is 2 97 Why not 2 2 ? pointer p holds the address of j now so why 97 is printed ?

mch
  • 9,424
  • 2
  • 28
  • 42
  • 3
    `p` is still passed by value, being a pointer doesn't give it any magic powers :) – George Jun 13 '17 at 20:07
  • 1
    pointer `p` in function `foo()` is a copy of pointer `p` in the function `main()`. Use `int **p` but you will have a lifetime problem. Because `j` don't live in `main()`. – Stargateur Jun 13 '17 at 20:11

4 Answers4

4

You can imagine the function call and its definition the following way. For clarity I'll rename the function parameter as q.

foo(p);

void foo( /*int *q*/ )
{
    int *q = p;
    int j = 2;
    q = &j;
    printf("%d ", *q);
}

As it is seen the function parameter (in this case q) is a local variable of the function that is initialized by the value of an argument (in this case by the value of the argument p)

So any changes of the local variable (q) do not influence on the original argument (p).

After exiting the function the local variable will not be alive.

If you want to change the argument itself you should pass it by reference. For example

void foo( int **p )
{
    int j = 2;
    *p = &j;
    printf("%d ", **p);
}

However after exiting the function the original argument/variable p will be invalid because it stores the address of a non-alive local variable of the function j.

So an attempt to access the memory that was occupied by the function's local variable j results in undefined behavior of the program.

You could make the program correct by declaring the local variable j as having static storage duration. For example

void foo( int **p )
{
    static int j = 2;
    *p = &j;
    printf("%d ", **p);
}

and call the function like

foo(&p);
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

In foo, you assign a new value to p. However this is a copy of the value of p in main, so the change is not visible in main.

If you dereferenced p, then it would change the value if i in main:

void foo(int *p)
{
    *p = 2;
    printf("%d ", *p);
}
dbush
  • 205,898
  • 23
  • 218
  • 273
1
p = &j;

just changes the value of the local variable p. This has no effect on the caller's p variable (because p was passed by value) or the variable that p previously pointed to (because you didn't indirect through it). If you want to change the caller's data, write:

*p = j;
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

Go through the above code line by line. Here I have written comments as control passes through each of the lines...

#include<stdio.h>

void foo(int*);
int main()
{
    int i = 97, *p = &i;   //Lets assume i has address 2000  
    foo(p);                //p contains 2000 which is passed to foo. go to foo at 1.
    printf("%d ", *p);    // when control comes back no change to p it 
                          //still points to 2000 which stores 97 
    getch();
}

void foo(int *p) 1: // in foo another local variable p is created. 
                   //Let's call this lp. lp has now address 2000. i.e lp 
                   //and p both point to i but one locally exists in a 
                   // function and will be destroyed when control comes out 
                   // of the function 
{
    int j = 2;
    p = &j;        // now local p i.e lp points to another var j 
                   //  address. Suppose lp has address 3000 now.  
    printf("%d ", *p);  //val at address in lp is 2
}
Shaurya
  • 313
  • 1
  • 12