3

Possible Duplicate:
What is the difference between char s[] and char *s in C?

More of a general question rather than trying to fix something, I've been reading the C programming language book and they take care to make the distinction between

char amessage[] = "blah";
char *pmessage = "blah";

The difference being one is a char array and the other a pointer to a string constant. They say modifying the char array is acceptable but you shouldn't modify string constants as it triggers undefined behavior. My question is: isn't the string constant stored in memory the same way the char array is? Why can I modify it as in

char *p = "this is a string constant";
*(p+2) = 'a';
printf("%s", p);

Ends up printing "thas is a string constant" as you might expect. I can understand how it would make sense as a string constant shouldn't end up being changed at run time, as it might confuse others/yourself working on your code not expecting it's value to change but in purely functional terms what is wrong with it, what is the undefined behavior that might trigger and how mechanically could it backfire when a char array wouldn't? I'm just wondering if I'm missing something about how string constants work in memory and how they are seen by the compiler.

Joshua
  • 40,822
  • 8
  • 72
  • 132
ameer
  • 2,598
  • 2
  • 21
  • 36

3 Answers3

4

At least on my computer, the following program crashes:

#include <stdio.h>
int main() { 
  char *p = "this is a string constant";
  *(p+2) = 'a';
  printf("%s", p);
}

If it appears to be working for you (which it might on certain embedded compilers), you're just getting lucky. Undefined behavior means the program is allowed to do anything. See http://blog.regehr.org/archives/213 .

See also What is the difference between char s[] and char *s?.

Community
  • 1
  • 1
servn
  • 3,049
  • 14
  • 8
  • I was using vc2010. Thanks for finding the other question didn't see it when I searched :D – ameer May 12 '11 at 05:02
  • Most embedded compilers will store string literals in true ROM, so they are less likely to allow the modification. Older compilers for RAM-based systems such as DOS are more likely to allow this. – Lundin May 12 '11 at 06:43
1

In case of char array the content of the string literal "blah" are copied on to the stack as well. So you can modify it without invoking UB because after all its just a copy.

In case of char * you actually try to modify the original string literal and as per the Standard that is UB.

Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
0

With a string constant, there's not guarantee about where the data will be stored -- the compiler is free to do any tricks it wants, because you're supposed to be forbidden from writing to it. So for example, it's not unheard of for the pointer to actually point to the spot in the loaded executable code itself where the string constant is defined.

tylerl
  • 30,197
  • 13
  • 80
  • 113