As pointed out in other answers, you are writing outside the bounds of the array. The original string a changes because it happens to be exactly after b in memory as you can see in the debug window.
Before the loop, memory looks like this:
b a
|00|WHat?00000|
After the loop, memory looks like this:
b a
|WH|at?0?00000|
This explains why
- a is changed
- the original questionmark in a is still there (you only write 6 characters - two into the location reserved for b, 4 (including null terminator) into the location of a)
Of course this is undefined behavior as already mentioned by Vlad Lazarenko, but it explains the behavior for your compiler/settings/version/etc.
A constant pointer only exists for the compiler. It ensures that you cannot explicitly manipulate its data, but if you have memory leaks, nothing can be guaranteed.