当你这样做时
char* something = "a string literal";
编译器把"a string literal"
进入可执行映像本身,并分配一个指向该内存的指针something
。您不允许修改此内存,并且很多时候该字符串所在的内存被标记为只读,因此任何对其进行写入的尝试都会导致访问冲突,就像您遇到的那样。
当你这样做时
char something[] = "a string literal";
您实际上是在堆栈上创建一个名为的数组something
and 初始化它与"a string literal"
。这相当于做char something[] = {'a', ' ', 's', 't', 'r', ..., 'a', 'l', 0};
。由于该内存位于堆栈上,因此您可以自由修改它。
char* something = "a string literal"
好像
stack executable
------------- ---------------------
|~~~~~~~~~~~| | ~~~~~~~~~~~~~~~~~ |
| something | -----------------> | a string literal0 |
------------- | ~~~~~~~~~~~~~~~~~ |
---------------------
Whereas char something[] = "a string literal"
好像
stack
-----
|~~~|
| a | <- something is an alias for this location
| |
| s |
| t |
| r |
| i |
| n |
| g |
| |
| l |
| i |
| t |
| e |
| r |
| a |
| l |
| 0 |
-----
Where ~~~
意思是“其他记忆等”。
注意
char* x = "string literal";
实际上是无效的,不应该编译,因为你无法转换char const[x]
to a char*
。它应该是const char* x
, not char* x
,但一些旧的和不合格的编译器错误地允许这种行为。