为何两段修改字符串字面量的C代码结果不同:一段成功一段触发段错误
为什么两段C代码修改字符串的结果不同?
第一段可正常运行的代码
#include <stdio.h> #include <stdlib.h> int main() { char w[] = "hello"; char *ptr; ptr = w; printf("\nw = %p\n", w); printf("ptr = %p\n", ptr); printf("%s\n", ptr); *(ptr + 1) = 'r'; printf("%s\n", ptr); }
第二段触发段错误的代码
#include <stdio.h> #include <stdlib.h> int main() { char w[] = "hello"; char *ptr = "hello"; printf("\nw = %p\n", w); printf("ptr = %p\n", ptr); printf("%s\n", ptr); *(ptr + 1) = 'r'; printf("%s\n", ptr); }
两者的核心差异在于内存区域的属性:
- 第一段里的
char w[] = "hello";是将字符串字面量"hello"复制到栈内存的数组中,栈内存属于可写区域,所以通过指针修改数组内容完全合法,程序能正常执行。 - 第二段里的
char *ptr = "hello";是让指针直接指向字符串字面量本身的存储地址,而字符串字面量在大多数编译器中会被放在只读数据段(比如.rodata),这块内存不允许写入操作。当代码尝试修改只读内存时,操作系统会触发段错误,阻止非法内存访问。
你可以观察两段代码打印的w和ptr地址,会发现它们指向完全不同的内存区域,这也能直观证明两者的存储位置差异。
内容的提问来源于stack exchange,提问作者Akshat Rastogi
相关产品推荐
相关产品推荐

