“C”程序中的分段错误

时间:2018-06-08 08:02:17

标签: c linux segmentation-fault

我正在尝试了解何时生成分段错误的原因。 我写了一个写入无效随机地址的小程序。

我没有看到此程序的分段错误 -

 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)
$

请问有什么解释吗?

2 个答案:

答案 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页面: