Because a char*
isn't a string. It's just a pointer to some character, with the convention that there are more characters to follow and that the last one is a '\0'
.
A character literal in C (and thus in C++) like "abc"
is just an array of characters, with the compiler silently adding a '\0'
. When you assign an array to a pointer, the array silently converts a pointer to the first element. The result is that
at = "tw";
means, the pointer at
is assigned the address of the first character in the string literal "tw"
. By this, it will lose its old value. Since this was the address of a dynamically allocated character array, you are leaking this array.
When you later assign to a character in the array at
now points to, you are assigning a new value to some character in the string literal. That's invoking undefined behavior and the program hanging or crashing immediately is probably the best that could happen to you when you do this. (On many platforms you're writing to read-only memory doing so.)
Later you pass at
to delete[]
(and not delete
, since you called new[]
, not new
). In doing so, you pass it the address of the string literal, instead of the allocated character array. This will, of course, mess up the heap manager. (VC's runtime library catches this in Debug mode.)
std::strcpy
, on the other hand, copies a string character by character from one array to another array. No pointers will be changed, only pieces of memory are copied. The pointer to the target array still points to the target array afterwards, only the data in that array has changed.