As @clcto mentions in the first comment the variable i is local to function and it get de-allocated when function returns.
Now why uncommenting the two print statements in function fun() make the value of p to be 10?
It can be because of many reasons which may be dependent on internal behavior of C and your system. But my guess is that it is happening because of how print works.
It maintains a buffer that I know. It fills it and then print it to the console when it get filled completely. So the first two print calls in fun() push i to the buffer, which is not yet filled completely. So when you are returning from fun() it may be possible that i doesn't get de-allocated because buffer is using it (or may be any other reason which I am not sure of but due to buffer i is preserved.)
To support my guess I tried to flush the buffer before printing again and now it doesn't prints 10. You can see the output here and the modified code is below:
#include <stdio.h>
//returning a pointer
int *fun()
{
    int i = 10;
    printf ("%u\n",i);
    printf ("%u\n",&i);
    return &i;
}
int main()
{
    int *p;
    p = fun();
    fflush(stdout);
    printf ("p = %u\n", p);
    printf ("i = %u \n",*p);
    return 0;
}
I think my guess is wrong, as @KayakDave pinted out. It just get fit to the situation completely. Kindly refere to his answer for correct explanation.