在 C 中,我尝试编译以下两个代码:
(1)
char a[] = "hello";
a[1] = 'b';
(2)
char *a = "hello";
a[1] = 'c';
第一次编译成功,但第二次给出分段错误。我知道,在这两种情况下,'a' 都代表字符指针。你能解释一下这两种情况下的不同行为吗?事实证明,在第二种情况下,我可以使用 a[i] 访问元素但不能更改它。
在 C 中,我尝试编译以下两个代码:
(1)
char a[] = "hello";
a[1] = 'b';
(2)
char *a = "hello";
a[1] = 'c';
第一次编译成功,但第二次给出分段错误。我知道,在这两种情况下,'a' 都代表字符指针。你能解释一下这两种情况下的不同行为吗?事实证明,在第二种情况下,我可以使用 a[i] 访问元素但不能更改它。
问:我知道,在这两种情况下,'a' 都代表字符指针。
不
因为当您声明为char *a = "hello";
then是常量字符串文字a
的指针a[i] = 'A';
时,您正在尝试在非法的只读内存上写入。
而在第一个声明char a[] = "hello";
中,a
任何数组及其内容都由字符串初始化,"hello"
该数组a[]
可以稍后在您的代码中修改。做a[i] = 'A';
是完全正确的。
问:第一次编译成功,但第二次出现分段错误。
您的代码已编译,因为语法a[i] = 'A';
正确。但是在第一种情况下 ( char *a = "hello";
) 指令
a[1] = 'c';
修改常量字符串文字是非法的内存操作符,该指令会导致运行时环境可以检测到的有效内存位置上的无效操作并发送终止信号 SIGSEGV 导致您的程序以分段终止-过错。
char *a = "hello";
表示指向常量字符串的指针,并且您正尝试在只读内存位置上写入,因此您遇到了分段错误。
第二种情况是undefined behavior
,您试图修改字符串文字的内容。由于它是未定义的,它可以表现出任何行为,包括看似正常工作,但在这种情况下,您会遇到分段错误。