我试图了解何时生成分段错误。 我写了一个小程序,它写入一个无效的随机地址。
我没有看到这个程序的分段错误 -
int main (void)
{
int c = 6;
*(&c + 1000) = 5;
printf ("0x%llx - %dn", (unsigned long)&c, c);
return 0;
}
其中输出:
$ gcc segmentationFault.c
$ ./a.out
0x7ffc2f709b5c - 6
$
但是,我在以下代码中遇到了一个 seg 错误 -
int main (void)
{
int c = 6;
*(&c + 3000) = 5;
printf ("0x%llx - %dn", (unsigned long)&c, c);
return 0;
}
它产生:
$ gcc segmentationFault.c
$ ./a.out
Segmentation fault (core dumped)
$
请解释一下吗?
当程序访问不允许访问的内存时,会发生分段错误。在您的示例中,程序仍然可以访问c+1000
,而c+3000
不再可以访问。但是,由于它是未定义的行为,即使*(c+1)
也可能导致分段错误。
你的问题有不同的观点:一个是C语言所要求的,一个是你的实现做什么。
对于 C 语言部分:您正在调用未定义的行为,因为c
是单个变量,&c
是指向大小为 1 的数组开头的指针。因此,取消引用&c + i
对于任何i != 0
都是UB。UB 意味着从语言的角度来看,将 int 返回到最终机器死亡可能会发生任何事情。这里无话可说。
对于实现部分,seg 错误是尝试读取驻留在系统中未绑定到进程的页面,该页面提供内存页(可能具有虚拟地址,这意味着将进程空间中的地址映射到物理内存中的地址的表(。在 Linux 上,/proc/{pid}/maps
和/proc/{pid}/pagemaps
提供有关进程映射的信息。有关它的更多详细信息,请参阅以下 SO 页面:
- 在 Linux 中是否有任何用于从虚拟地址确定物理地址的 API? /
- proc/[pid]/pagemaps 和/proc/[pid]/maps | Linux