char hello[] = {'h', 'e', 'l', 'l', 'o', '\0'};
This creates an array of 6 bytes in writable memory (on the stack if this is inside a function, in a data segment if directly at global scope or inside a namespace), to be initialised with the ASCII codes for each of those characters in turn.
char *hello = "hello";
"hello"
is a string literal, which typically means:
the OS loader code that loads your program into memory and starts it running will have copied the text "hello\0" from your executable image into some memory that will then have been set to be read only, and
a separate variable named "hello" - which is of whatever size pointers are in your program (e.g. 4 bytes for 32-bit applications, 8 for 64-bit) - will exist on the stack (if the line above appears inside a function) or in writable memory segment (if the line is at global or namespace scope), and the address of the former textual data will be copied into the hello
pointer.
you can change hello
to point somewhere else (e.g. to another language's equivalent text), but normally shouldn't try to change the string literal to which the above code points hello
... see below.
But in correct c++ the second should be:
const char *hello = "hello";
Yes - that's much better. For backwards compatibility, C++ has historically allowed non-const
pointers to string literals, but actually modifying them wasn't guaranteed to be possible. Some compilers always, or can optionally (when asked by command line arguments), put string literals in writable memory. But, even if they are writable, changing them leads to lots of potential for errors. Say you have code like this and compiler flags to allow it to compile:
char* end = "end";
if (mixed_case_mode) end[0] = 'E';
if (s == "end") ...;
Then some completely unrelated code that does this...
std::cout << "this is the " << (x ? "start": "end");
...might start printing "End" if all mentions of "end" shared the same memory - a common and desirable optimisation. Turning this off can be quite wasteful, and while it allows this hackery to work with less unintended side effects to unrelated uses of the text, it's still very hard to reason about the code and debug when if (s == "end")
might not actually be comparing s
to "end"
.