1.char *str1 = "Hello";
Generally the string literals would be stored in the read only data
section of the resulting object code, post compilation. So, modifying
the contents of the memory location addressed by "str1" would result in
seg fault. This might be compiler dependent though.
That specific behavior is compiler-dependent, but modifying string literals
is not allowed by the Standard (any of them). Since this newsgroup deals with
the standards and how they relate to various programs and programming constructs,
it's better to say that the behavior is undefined.
Although, "str1" itself can be modified.
The following is valid:
char *str1 = "Hello";
str1 = 0; // Allowed
To be more clear, you might replace 0 with NULL. This is just a stylistic issue.
2.char arr1[] = { "Hello" };
Contents of the memory addressed by "arr1" can be modified. "arr1"
itself cannot be modified.
That is the following is invalid:
char arr1[] = { "Hello" };
arr1 = 0; // Not allowed.
No, that is still allowed: The array 'decomposes' into a pointer and
you can modify a non-const-qualified pointer at will.
What's giving me fits is what that is a pointer /to/. I don't think the
line of code is valid, in other words. It would be just fine if it was
defined like this:
char *arr1[] = { "Hello" };
As it stands, however, I don't think the definition is valid.
3. char arr2[] = { 'H', 'e', 'l', 'l', 'o' };
Same comments as above for "arr2" hold true here.
Well, no. arr2 is an array of char of size 5, but it cannot be used
as a string by most standard string-handing functions as it lacks
nul-termination. An array can decompose into a pointer to the first
element under certain conditions (such as when it is passed into or
returned from a function) and that array would decompose into a
pointer to char. Since nothing is const-qualified, you can modify that
array's contents and the value of the pointer it can decompose into.
Thus, both of these are legal:
arr2[1] = 'a'; /* The array is now 'Hallo' */
arr2 = NULL; /* The array is now unreachable. */