所以我有以下程序:
int main(){
char* one = "computer";
char two[] = "another";
two[1]='b';
one[1]='b';
return 0;
}
它在“one[1]='b'”行上出现段错误,这是有道理的,因为指针“one”指向的内存必须位于只读内存中。然而,问题是为什么“two[1]='b'”行没有段错误?查看 gcc 的汇编输出:
.file "one.c"
.section .rodata
.LC0:
.string "computer"
.LC1:
.string "another"
.text
.globl main
.type main, @function
main:
我们看到两个字符串都位于 rodata 部分,因此它们是只读的。那么为什么“two[1]='b'”行没有段错误呢?
one
直接指向位于只读页中的字符串。另一方面,two
是在堆栈上分配的数组,并使用一些常量数据进行初始化。在运行时,可执行文件的只读部分中的字符串将被复制到堆栈中。您正在修改的是堆栈上该字符串的副本,而不是只读内存页。
从更高层次的角度来看,从语言的角度来看,"abcd"
是类型的表达式const char*
并不是char*
。因此,修改此类表达式所指向的值会导致未定义的行为。该声明char* one = "something";
只是将指向字符串的指针存储在变量中(不安全,因为它正在抛弃const
修饰符)。这char two[] = "something";
是完全不同的。它实际上是声明一个数组并初始化它,就像int a[] = {1,2,3};
。这里引号中的字符串是初始化表达式。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)