-2

In C, I tried to compile following two codes:
(1)

char a[] = "hello";
    a[1] = 'b';

(2)

char *a  = "hello";
  a[1] = 'c';   

First compiles successfully but second gives segmentation fault. I know, in both cases 'a' represent character pointer. Can you explain me the different behavior in the two cases. It turns out that, in second case I can access elements using a[i] but can't change it.

Alicia
  • 1,152
  • 1
  • 23
  • 41
west007
  • 97
  • 3
  • 12

3 Answers3

4

Q: I know, in both cases 'a' represent character pointer.

No

Because when you declare as char *a = "hello"; then a is pointer of constant string literal and by doing a[i] = 'A'; you are tring to write on read only memory that is illegal.

Whereas in first declaration char a[] = "hello";, a is any array and its contents initialized by string "hello" that array a[] can be modify latterly in your code. and doing a[i] = 'A'; is perfectly correct.

Q: First compiles successfully but second gives segmentation fault.

Your code compiled because syntax-wise a[i] = 'A'; is correct. But in first case (char *a = "hello";) instruction a[1] = 'c'; modifying on constant string literal that is illegal memory operator, this instruction causes invalid action on a valid memory location that can be detected by runtime environment and send a termination signal SIGSEGV which results your program terminated with a segmentation-fault.

Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
  • 2
    It is not correct to say that it is in `read only` memory, it probably is but it is implementation defined: http://stackoverflow.com/questions/2589949/c-string-literals-where-do-they-go . All you can say is that it is `undefined behavior`. – Shafik Yaghmour Jul 29 '13 at 15:40
  • @ShafikYaghmour yes, but its on most/standard compilers its read only, I have give you a + after reading your answer. Thanks for the link :) – Grijesh Chauhan Jul 29 '13 at 15:43
  • 2
    Yes, most current compilers will put string literals in read-only memory, but they didn't always do that, and I believe you can still tell them not to. – This isn't my real name Jul 29 '13 at 16:51
  • @ElchononEdelson I think `-Wwrite-strings` force it to put in read only memory only by default it may be implementation dependent. Is this? – Grijesh Chauhan Jul 29 '13 at 17:03
  • 1
    The standard says that string literals are arrays of `char` (or arrays of `wchar_t`), and it says "If the program attempts to modify such an array, the behavior is undefined". It does not require the compiler to put them into read-only memory. Time was, compilers generally didn't, time is, compilers generally do. (Unless you're still using Turbo C...). The `-Wwrite-strings` doesn't change a behavior, it just turns on a warning. According the the GCC documentation, the option to enable writable string constants was`-fwritable-strings`, and was deprecated in GCC 3.4, and removed in GCC 4.0. – This isn't my real name Jul 29 '13 at 17:19
2
char *a = "hello";

Indicates a pointer to a constant string and you are trying to write on an read only memory location and hence you are getting the segmentation fault.

Santhosh Pai
  • 2,535
  • 8
  • 28
  • 49
1

The second case is undefined behavior, you are attempting to modify the contents of a string literal. Since it is undefined it can exhibit any behavior including seemingly working correctly but in this case you have a segmentation fault.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740