The difference is that in the first one, p is a pointer to a constant string. Your program crashes because you're running it in an environment that detects writes into this read only memory. Even if the program didn't crash, it would still be wrong.
In the second one, p is declared as array of 6 characters on the stack. The content is 'h', 'e', 'l', 'l', 'o', NULL. You are free to change any characters in this range of 6 bytes.