0

Why do I get an hangtime error when running the following code?

int main(void)
{
    char *string_array[2];

    string_array[0] = "hI";
    string_array[1] = "tHERE";

    string_array[0][0] = 'H';

    return 0;
}

However, if I call the Individual String Characters and print them using the same "Handle" it works.(See Working code below)

int main(void)
{
    char *string_array[2];

    string_array[0] = "hI";
    string_array[1] = "tHERE";

    printf("%c", string_array[0][0]); //Prints out h, the first char of the first string in the array

    return 0;
}
Cœur
  • 37,241
  • 25
  • 195
  • 267

2 Answers2

2
char *string_array[2];

string_array[0] = "hI";
string_array[1] = "tHERE";

string_array is pointing to locations where string literals reside.

String literal hi resides in reads only location and can not be modified. Trying to modify them leads to undefined behavior.

To modify, allocate enough memory including null termination character and then copy the string.

Mahesh
  • 34,573
  • 20
  • 89
  • 115
0

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).

Dave Lillethun
  • 2,978
  • 3
  • 20
  • 24