问题
This works:
int main()
{
char *t = "Hello";
t = "World";
printf("%s", t);
}
But this gives segmentation fault:
int main()
{
char *t = "Hello";
strcpy(t, "World"); // the only difference
printf("%s", t);
}
Why?
回答1:
Strings that you define explicitly - e.g. "Hello"
- are typically placed in an area of read-only memory. These strings cannot be changed.
In the first example, you are not changing the "Hello" string into the "World" string. You are re-assigning t
so that it points to "World" instead of "Hello". The "Hello" string is still hanging around, untouched, in read-only memory.
Here's the initial state:
t -> "Hello"
"World"
Here's the second state:
"Hello"
t -> "World"
In the second example, you are trying to overwrite the "Hello" string. This cannot be done.
You should really change your declaration from char *t
to const char *t
. I think GCC can be configured to enforce this.
回答2:
The first changes the value of t
to point from the address of "Hello"
to the address of "World"
. The second attempts to overwrite the data "Hello"
itself.
回答3:
In the first example the pointer t
is made to point to a string constant "Hello"
, and then immediately afterwards to the string constant "World"
; the latter value is then printed.
The code in the second example crashes with segfault, because string constants are not writeable. (strcpy tries to modify the memory that holds the text "Hello"
). GCC places string constants into a read-only section, unless compiled with -fwriteable-strings
.
The code
char *test = "Hello";
means that the compiler+linker place a string of bytes "Hello\0" in a read-only section, and the test
points into the first character thereof. Any attempt to write through this pointer would be harshly punished by the operating system.
On the other hand
char test[] = "Hello";
declares an array of 6 characters, with initial value of ({ 'H', 'e', 'l', 'l', 'o', '\0' }
).
Some old programs assumed that string constants are writeable; thus requiring GCC to support compiling those programs with the -fwriteable-strings
command line switch.
回答4:
The assignment t = "World"
changes only the pointer, while the strcpy
changes the memory to which t points. String literals may live in a read-only segment.
回答5:
char* t
is a pointer. In the first example, you are merely assigning the pointer from one string literal to another: first t
pointed to "Hello"
, then to "World"
. This is perfectly legal.
However, the string literals themselves are literals--they cannot be changed. Typically they are in a read-only section of memory. In the second example, you are attempting to change what is in the memory allocated to the string literal "Hello"
by overwriting it with "World"
. That is illegal and you will get a segmentation fault.
回答6:
In char *t="Hello"
t
assign "Hello" in read only location. So writing to readonly location make segmentation fault.
There is the difference between assigning and copying.
First example you trying to assign the address of another string to t
.
In second example you trying to write into readonly location.
use char t[] = "Hello"
. Here t can be overwrite
more explanation Here
回答7:
"Hello" is a string constant. It's not meant to be written on, by the definition of constant.
In your first example, 't' is a pointer, and it can point(be assigned) either string constant.
来源:https://stackoverflow.com/questions/18388833/segmentation-fault-with-strcpy