At first, you need to distinguish p1
and p2
within main and p1
, p2
within the functions, which are not the same. So I will rename the parameters of foo and bar into fp1
, fp2
, bp1
, fp2
to be able to differentiate more clearly. This won't change anything in behaviour.
So main first calls foo(p1, p2);
. fp1
and fp2
then are copies of the pointers p1
and p2
. Within foo:
fp1 = fp2;
fp2 is assigned to fp1. So both fp1 and fp2 hold the address of the array p2 was assigned to (i. e. m
within main).
*p1 = *p2 + 1;
as both p1 and p2 hold the address of m (or m[0], which is the same for arrays), m[0] is incremented (was 4, now is 5).
Then calling bar(&p1, &p2);
. So bp1
and bp2
now hold the addresses of the two pointers p1
and p2
within main (i. e. you can modify p1 and p2 themselves from within bar!), which is going to happen then, too:
bp1 = bp2;
again both pointers hold the same address, which is the one of p2 within main (still with address of m[0]).
*bp1 = *bp2 + 1;
as both bp1 and bp2 point to the same pointer, results in incrementing this pointer, so effectively increments p2, now pointing to m[1].
**bp1 = **bp2 + 2;
bp1 and bp2 both point to p2, which points to m[1]. So m[1] is incremented by 2 (m[1] was 5, now is 7!).
Finally printing the values. Remember, p2 itself was modified within bar, now pointing to m[1], which again was modified to 7, so the result you did not expect...