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);