可能重复:
为什么在写入字符串时会出现分段错误?
我有以下程序:
char *s = "abcdf";
char s1[50] = "abcdf";
s1[0] = 'Q'; // Line 1
s[0] = 'P'; // Line 2
为什么Line 1
正常工作并Line 2
导致程序崩溃?
可能重复:
为什么在写入字符串时会出现分段错误?
我有以下程序:
char *s = "abcdf";
char s1[50] = "abcdf";
s1[0] = 'Q'; // Line 1
s[0] = 'P'; // Line 2
为什么Line 1
正常工作并Line 2
导致程序崩溃?
第 2 行指向可执行文件的只读数据部分,而在第 1 行,程序s1
使用给定字符串初始化数组。这存储在堆栈中,您可以对其进行修改。
char *s = "abcdf";
char s1[50] = "abcdf";
s1[0] = 'Q'; // Line 1
s[0] = 'P'; // Line 2
这里,s
是一个有保证的可修改指针,它可能是全局变量或局部堆栈变量,具体取决于您将该定义放在程序范围内还是在函数内。在你开始使用它之前的某个时候,编译器需要安排将文本“abcdf”的地址加载到s
. 通常在现代操作系统中,“abcdf”本身将位于只读内存区域中,其中将程序文件读入内存以准备执行的“加载程序”告诉 CPU 本身允许读取但不允许写入操作。所以s
- 这是可修改的 - 指向不是的“abcdf”。
s1
是 50 个字符的保证可修改数组。在您开始使用它之前的某个时候,编译器需要安排将文本“abcdf”复制到该可修改缓冲区中。然后,您可以像使用s1[0] = 'Q'
.
s[0] = 'P'
使用指针s
在只读内存中找到原始的不可修改/常量文本“abcdf”,然后尝试更改它。如上所述,CPU 通常已配置为通过生成 CPU 异常/陷阱/信号/中断来做出反应(术语因制造商而异)。你的程序会失败。