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