In C (not C99) the sizeof operator is strictly a compile time calculation. so when sizeof (*p) [a dereferenced ptr to an integer] is evaluated then the size of int is four.
Note. the (*p) portion of that statement is a "cast" operator. So, sizeof is NOT a function call as in sizeof(xyz), rather it is like sizeof var_name or sizeof (int *).
When your program runs it changes the object pointed to by p, but the value of sizeof (*p) was already computed and hard-coded into your executable load module.
I think your confusion is that you were thinking that C would figure out what data type p was pointing to when your program runs.