I'm guessing when you say "doesn't behave like" you mean one throws an illegal access exception (or something similar) while the other gives a compile time warning or error?
The answer is that in the first case, you're creating a pointer to your own memory, and copying the c9ontents into it. At that point the compiler forgets it used to be a pointer to static memory; the run time system, however, doesn't forget.
In the other case, the compiler "knows" p is a pointer to static memory, and so has the chance to say "whoa, dude, can't do that".
But this is a bit of a guess without knowing exactly what it does differently. it's also going to be compiler and implementation dependent.