When you say something "Hello World"
in your code, that is a string literal. When you run your program, those characters (plus the terminating \0
) will be placed somewhere in your process' memory. Every time "Hello World"
appears in your code, it is replaced with the memory address (char*
) of the beginning of that string literal. In this way, it is much like an ordinary C-string (i.e., you have a char*
that points to the first character in the string, and the last character is followed by a \0
so you can tell where the string ends). However, there is one important difference: String literals are not put in the same part of memory where your other variables are located. Specifically, the part of memory where string literals are located is (normally) read-only. That's a view of the physical representation. From a language perspective, we would simply say that "string literals are constants" meaning they cannot be assigned.
So when you say:
string_array[0] = "hI";
string_array[0][0] = 'H';
string_array[0]
is pointing to a string literal ("hI") which is not writable according to C. When you say string_array[0][0] = 'H';
you are trying to make an assignment to the string literal. What (probably) physically happens is that this attempts to write to a read-only memory address, which triggers a fault and causes the OS to terminate your process.
The reason the compiler doesn't catch this is because string_array
is an array of char*
and that type is technically assignable. String literals are actually const (and I probably should have said above that their type is const char*
instead of char*
). So when you make the assignment string_array[0] = "hI";
you are actually casting a const char*
to a char*
. C is a very "permissive" language. :) So when you tell it to cast a const type to a non-const type, it is all too happy to comply. Then when you tell it to assign to the now non-const type variable, it is again happy to comply. So that's why the problem doesn't actually show up until runtime, when the hardware and OS use write-protected memory to prevent errors.
The way to fix it, as others have mentioned, and assuming you do want to make that assignment, is to create a character array and copy the string literal into it (e.g., using strncpy
).