Be free (of historical lazyness), be wise! Pointers are not arrays! Tutorials have lied you!
In the first example, you're modifying a pointer to a constant string literal, and that's undefined behaviour. Anything can happen then!
Meanwhile, in the second case, the string itself is stored inside the array, and the array itself is in the stack. Thus, the second example exposes more than a plain innocent array that's modifiable.
The s2
pointers make no difference in all this. IMHO, the fact that the first case is compilable is just historical lazyness, otherwise known as backwards compatibility.
BTW: Are you assigning string literals to char
s? That's undefined behaviour too!