The following code receives seg fault on line 2:
char *str = "string"; str = 'z'; // could be also written as *str="z" printf("%s\n", str);
While this works perfectly well:
char str = "string"; str = 'z'; printf("%s\n", str);
Tested with MSVC and GCC.
See the C FAQ, Question 1.32
Q: What is the difference between these initializations?
char a = "string literal";
char *p = "string literal";
My program crashes if I try to assign a new value to
A: A string literal (the formal term
for a double-quoted string in C
source) can be used in two slightly
- As the initializer for an array of char, as in the declaration of
char a, it specifies the initial values
of the characters in that array (and,
if necessary, its size).
- Anywhere else, it turns into an unnamed, static array of characters,
and this unnamed array may be stored
in read-only memory, and which
therefore cannot necessarily be
modified. In an expression context,
the array is converted at once to a
pointer, as usual (see section 6), so
the second declaration initializes p
to point to the unnamed array’s first
Some compilers have a switch
controlling whether string literals
are writable or not (for compiling old
code), and some may have options to
cause string literals to be formally
treated as arrays of const char (for
better error catching).
Normally, string literals are stored in read-only memory when the program is run. This is to prevent you from accidentally changing a string constant. In your first example,
"string" is stored in read-only memory and
*str points to the first character. The segfault happens when you try to change the first character to
In the second example, the string
"string" is copied by the compiler from its read-only home to the
str array. Then changing the first character is permitted. You can check this by printing the address of each:
Also, printing the size of
str in the second example will show you that the compiler has allocated 7 bytes for it:
Most of these answers are correct, but just to add a little more clarity…
The “read only memory” that people are referring to is the text segment in ASM terms. It’s the same place in memory where the instructions are loaded. This is read-only for obvious reasons like security. When you create a char* initialized to a string, the string data is compiled into the text segment and the program initializes the pointer to point into the text segment. So if you try to change it, kaboom. Segfault.
When written as an array, the compiler places the initialized string data in the data segment instead, which is the same place that your global variables and such live. This memory is mutable, since there are no instructions in the data segment. This time when the compiler initializes the character array (which is still just a char*) it’s pointing into the data segment rather than the text segment, which you can safely alter at run-time.