18

In this statement:

char *a = "string1"

What exactly is string literal? Is it string1? Because this thread What is the type of string literals in C and C++? says something different.

Up to my knowledge

int main()
{
    char *a = "string1"; //is a string- literals allocated memory in read-only section.
    char b[] = "string2"; //is a array char where memory will be allocated in stack.

    a[0] = 'X'; //Not allowed. It is an undefined Behaviour. For me, it Seg Faults. 
    b[0] = 'Y'; //Valid. 

    return 0;
} 

Please add some details other than above mentioned points. Thanks.

Debug Output Showing error in a[0] = 'Y';

Reading symbols from /home/jay/Desktop/MI/chararr/a.out...done.
(gdb) b main
Breakpoint 1 at 0x40056c: file ddd.c, line 4.
(gdb) r
Starting program: /home/jay/Desktop/MI/chararr/a.out 

Breakpoint 1, main () at ddd.c:4
4   {
(gdb) n
6   char *a = "string1";
(gdb) n
7   char b[] = "string2";
(gdb) 
9   a[0] = 'Y';
(gdb) 

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400595 in main () at ddd.c:9
Community
  • 1
  • 1
Jeyaram
  • 9,158
  • 7
  • 41
  • 63
  • 1
    @elyashiv, the code is illegal as it is attempting to modify a string literal. – hmjd Oct 09 '12 at 08:30
  • 3
    I am unsure what the exact question is. For specific details on string literals, see section 6.4.5 of the C99 standard. – hmjd Oct 09 '12 at 08:31
  • Perhaps [this stackoverflow question](http://stackoverflow.com/questions/2589949/c-string-literals-where-do-they-go) may help, or [this one](http://stackoverflow.com/questions/2245664/string-literals-in-c). – Richard Oct 09 '12 at 08:33
  • 1
    You already know modifying string literals is UB and luckily you get segfault when you try to do that. GDB shows you get segfault when you modify it. What's the question here? – P.P Oct 09 '12 at 08:40
  • OK, so technically `char *a = "string1";` should generate a compiler warning about initializing a `char *` with a `const char *` value. I'm guessing that the only reason it doesn't is because far too much legacy code would start throwing warnings. – Edward Falk Jul 20 '16 at 01:42

1 Answers1

29

You can look at string literal as "a sequence of characters surrounded by double quotes". This string should be treated as read-only and trying to modify this memory leads to undefined behavior. It's not necessarily stored in read only memory, and the type is char[] and not const char[], but it is still undefined behavior. The reason the type is not const is backwards compability. C didn't have the const qualifier in the beginning. In C++, string literals have the type const char[].

So how come that you get segmentation fault?

  • The main point is that char *ptr = "string literal" makes ptr to point to the read-only memory where your string literal is stored. So when you try to access this memory: ptr[0] = 'X' (which is by the way equivalent to *(ptr + 0) = 'X'), it is a memory access violation.

On the other hand: char b[] = "string2"; allocates memory and copies string "string2" into it, thus modifying it is valid. This memory is freed when b goes out of scope.

Have a look at Literal string initializer for a character array

klutt
  • 30,332
  • 17
  • 55
  • 95
LihO
  • 41,190
  • 11
  • 99
  • 167
  • I just wanted more details on it. some threads confused me that `char a[] = "sdsf";` also a string literal. – Jeyaram Oct 09 '12 at 08:50
  • 1
    @rjayavrp: *"A string literal is a sequence of characters surrounded by double quotes"*. Yes, in `char a[] = "sdsf";`, `"sdsf"` is a string literal that is used to initialize array `a`. – LihO Oct 09 '12 at 08:57
  • Thanks. so I misunderstood that string literals are strings which are allocated memory in read-only section. It is not based on memory location :). – Jeyaram Oct 09 '12 at 08:59
  • 1
    @rjayavrp: "string literal" is just some term. The main point is that you retrieve address of read-only memory where your string literal is stored (`char *ptr = "string literal"`), and then you try to access this memory: `*(ptr + 1) = 'A'`... – LihO Oct 09 '12 at 09:03
  • Then why do I get this warning: "Incompatible pointer to integer type initializing const char with expression of type char[5]" when I do this: const char myyear = "2014";? –  Dec 04 '15 at 21:57
  • 1
    @moonman239: Because `const char myyear = "2014"` and `const char *myyear = "2014"` are different things. – LihO Dec 05 '15 at 08:22