So basically in main p is pointing to i and both p and i are local variables of main function.
Then the address of the pointer p is passed to foo.
In the function foo the parameter p is a constant pointer which is now pointing to the pointer p declared in main.
This statement *p = &j leads to the following indicated below
When you first print p (**p) inside the function foo you get the output 11(follow the arrow).
Once you return to main function the local variable j is destroyed (address held is released)
Therefore now when you try to print p from main it no longer prints 11 but random values. But be warned sometimes the memory of the local variable in foo may not be assigned to something else yet and you might still get the answer 11 11 11.