1) It is technically illegal in modern C++. Correct way is constchar * Greeting = "Hello World!";
2) You can assign values to pointers. You just need to make sure types are compatible:
1 2
int x;
int* magic = &x;
3) type of string literal "Hello World!" is constchar[13] which per array-to-pointer conversion rules can be converted to constchar*
3)
Is "Hello World?" being stored on the heap or on the stack?
It is irrelevant. It can be stored anywhere where compiler will see fit (and there technically no stack and heap in c++ standard). What important that it has static storage duration.
this does not work.
Because it was never allocated with new[]. Trying to delete something which does not have dynamic storage duration yields undefined behavior. For example, crash.
int * magicNumber = (int*)42;
Technically, this works just fine. The problem is that it isn't doing what your brain thinks it is.
'magicNumber' is a pointer to int, and you assign it the address '42', which is almost guaranteed to be a location your program is not permitted to access.
Hence, when you try to run the program, any attempt to access or modify *magicNumber causes abnormal termination.