-2

Please, someone explain why the following C program crashes:

void changeChar(char *string);

int main(int argc, char *argv[])
{
  char *test = "word";
  changeChar(test);
  return 0;
}

void changeChar(char *string) {
  *string = 'A';
}

while the following code works perfectly:

void changeChar(char *string);

int main(int argc, char *argv[])
{
  char test[] = "word";
  changeChar(test);
  return 0;
}

void changeChar(char *string) {
  *string = 'A';
}
LihO
  • 41,190
  • 11
  • 99
  • 167
  • Because `test[]` is a character array, while the first `test` is just a character pointer. – Mr Lister Jun 08 '13 at 20:50
  • 1
    @NullPointerException You are not aware the idea of "constants", are you. –  Jun 08 '13 at 20:57
  • ("avare of", of course. Damn 5-minute editing limit.) –  Jun 08 '13 at 21:04
  • @H2CO3, can you be more precise about me missing some constant concepts? – NullPointerException Jun 08 '13 at 22:18
  • @NullPointerException I meant, their existence as such. But this question (I mean your comment) shows that in fact you aren't, you just didn't know that string literals were constant (which is somewhat surprising for me, since they are almost always (incorrectly) referred to as "string constants"). –  Jun 08 '13 at 22:20
  • @H2CO3 you may think as you like and instead of pointing and repeating the same thing you could better provide a resource to liquidate my "ignorance" and so that I could be 100% sure that yes, smth is wrong in my vision of string literals – NullPointerException Jun 08 '13 at 22:27
  • @H2CO3 In C, string literals are not constants ... thus, you can assign them to pointers to non-const char. Of course, if you write to them, the result is UB, but that's a different matter. (Another matter is why anyone would want to use such a defectively specified language.) – Jim Balter Jun 09 '13 at 00:25
  • @MrLister Wrong and irrelevant. E.g., `char x; char* test = &x; changeChar(test);` works fine even though "test is just a character pointer". – Jim Balter Jun 09 '13 at 00:29

3 Answers3

5

The first program crashes because it tries to write the memory allocated to a string literal, which is an undefined behavior. The second program copies the string literal into writable memory, fixing the problem.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
5

Because

char *test = "word";

is not the same as

char test[] = "word";

The first one is string literal it MUST not be changed - changing it causes undefined behavior (as they are immutable).

The second one is a standard (mutable) array of chars.

By the way, the first one must be const char*, not char* (and this will even solve the issue - you'll get compile time error) (thanks to @ouah and @dasblinkenlight - didn't know, that there's a difference in this case)

Kiril Kirov
  • 37,467
  • 22
  • 115
  • 187
  • It must in C++ but not in C where the string literal is immutable but its type is `char[N]` and not `const char[N]`. – ouah Jun 08 '13 at 20:52
  • 1
    I does not have to be `const char*` in C, only in C++. – Sergey Kalinichenko Jun 08 '13 at 20:53
  • 1
    @dasblinkenlight Technically. But no sane programmer ever writes `char *justBecauseItsNotRequiredIDontConstQualifyIt = "breakthis";` –  Jun 08 '13 at 20:59
  • "as they are immutable" -- uh, no. Whether they are "immutable" is *undefined*, which is precisely why storing into them is *undefined behavior*. "But no sane programmer ever writes ..." -- wrong; sane (arguably) programmers have been known to write into string constants on systems where they known to be writable (e.g., M$ implementations with the flags set to allow writable string constants). I recently worked on some legacy code that did exactly that ... I didn't change it because it had been working for 18 years. – Jim Balter Jun 09 '13 at 00:33
2

Because char *test = "word"; defines a pointer to constant string literal that resides within the read-only memory. Trying to modify it results in undefined behavior.

Also have a look at:
What is the difference between char s[] and char *s?

And since this is quite common mistake, you'll find many duplicates:
Why do I get a segmentation fault when writing to a string initialized with "char *s" but not "char s[]"?
C: differences between char pointer and array
Is it possible to modify a string of char in C?

Community
  • 1
  • 1
LihO
  • 41,190
  • 11
  • 99
  • 167