我在学习操作系统时遇到这个问题,我真的很感兴趣操作系统如何检测数组索引是否超出范围并因此产生分段错误?
int main(){
char* ptr0;
ptr0[0] = 1;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码绝对会产生分段错误,因为 ptr0 没有分配任何内存。
但如果添加一行,情况就会改变。
int main(){
char* ptr0;
char* ptr1 = ptr0;
ptr0[0] = 1;
}
Run Code Online (Sandbox Code Playgroud)
这段代码不会导致任何错误,即使你将ptr0[0]更改为ptr0[1000],它仍然不会导致任何分段错误。
不知道为什么这条线有这么大的力量
char* ptr1 = ptr0
Run Code Online (Sandbox Code Playgroud)
我试图反汇编这些代码,但发现的信息很少。
有人可以从内存分配的角度向我解释一下吗?多谢。
当进程尝试访问不应该访问的内存时,就会发生分段错误,而数组读取越界则不一定。
在您的特定情况下,变量ptr0未初始化,因此如果您尝试读取它,则可能会读取任何值,并且它甚至不需要保持一致。因此,在第一个程序的情况下,读取的值碰巧是无效的内存地址,并且尝试从该地址读取会触发 sigfault,而在第二个程序的情况下,读取的值碰巧是有效的地址程序,因此没有生成段错误。
当我运行这些程序时,两者都导致了段错误。这演示了程序中存在尝试取消引用无效指针的未定义行为。
当程序具有未定义的行为时,C 标准不保证程序将执行的操作。它可能会崩溃,可能会输出意外的结果,或者可能看起来工作正常。