鉴于以下计划 .
int main() {
char *str = "hello word";
str[0] = 'a';
return 0;
}
上述程序会引发分段错误 . 我知道它会抛出,因为只读段包含hello世界,并且无法修改 . 如果在L1缓存(处理器内部)中完成从“h”变为“a”的存储指令,并且仅当页面从L3刷新到主存储器时MMU才会进入图像,几乎立即抛出分段故障 .
下面的代码实际上做了同样的事情,不会导致任何分段错误 . 为什么?
int main() {
char str[] = {'h','e','l','l','o',' ','w','o','r','l','d','\0'};
str[0] = 'a';
return 0;
}
2 回答
处理器高速缓存具有与每个高速缓存行相关联的标签,该标签告诉它应用于当前保存在该高速缓存行中的存储器的权限因此,在尝试写入高速缓存时,(通常)将立即捕获写入只读存储器的尝试;它不会等到该缓存行刷新到主存储器 .
就两个示例之间的差异而言,它非常简单:第一个定义静态分配的字符串文字 . 尝试修改该字符串文字会导致未定义的行为 . 第二个定义了一个初始化为特定值的char数组 - 但在初始化之后,它几乎与任何其他数组一样 . 特别是,很好地定义了修改数组内容的结果 .
在第二个,你正在复制 . 虽然在第一个你不是 .
这里
str
是在堆栈上创建的数组 . 要str
,正在复制内容 . 怎么进 -str
指向驻留在不可修改部分的数据 . 所以,你不能和尝试时的结果分段错误 .Description for comments
我没有't think, for the primitive data types C and C++ varies it'的规则 . 来自ISO / IEC 14882:2003(E), Section 8.5.2
因此,示例2清除了疑问 .