【问题标题】:Segmentation Fault doesn't come up immediately after accessing out-of-bound memory访问越界内存后,分段错误不会立即出现
【发布时间】:2015-01-31 20:54:19
【问题描述】:

我写了这段代码,并期待很快出现分段错误,但似乎我被允许访问我不应该能够访问的内存片段。

#include<stdio.h>
int main()
{
    int tab[1];
    tab[0]=42;
    int i;
    //Expecting Seg Fault from i==1...
    for(i=0;;i++)
    {
        printf("%d \t %d \n", i, tab[i]);
    }
    return 0;
}

我正在编译使用:

gcc -Wall -Wextra my_code.c -o segfault && ./segfault

在执行时,变量 i 在我得到分段错误之前达到了 1000 阶的值。

我的问题是:为什么到目前为止我还能阅读tab

PS:使用#include &lt;stdlib.h&gt; 并声明int * tab = (int*)malloc(sizeof(int)); 不会改变任何东西...

谢谢,最好的。

【问题讨论】:

  • 这么多重复我一个都挑不出来。
  • 非常感谢您的所有回答,也感谢您编辑标题。对于重复的主题,我很抱歉,我不知道正确的错误是“越界”而不是“分段错误”。

标签: c arrays segmentation-fault indexoutofboundsexception


【解决方案1】:

当您使用越界内存时,您将面对Undefined behavior。你不能定义一个叫做Undefined behavior的东西。

在你的情况下,它发生在i = 1000s,在其他情况下,它很可能发生在i=347左右..

分段错误是访问程序允许的堆栈地址空间之外的内存的结果。如果您在该内存范围内完成执行,它可能可以正常运行并以明显的正常工作让您感到惊讶。 out-of-bound 访问可能产生有效内存访问,直到您没有越过堆栈内存区域。

如果您遇到分段错误,请考虑自己幸运,因为这告诉您,出了点问题。否则,您将不知道由此产生的恐怖。

注意:作为建议,问题标题应更改为.. comes up very late 或类似的名称

【讨论】:

    【解决方案2】:

    您的数组tab 将位于堆栈上的某个位置。当您打印超出数组末尾时,您实际上是在打印堆栈上其他内存位置的值。

    需要大约 1000 次迭代才能得到 seg 错误的原因是堆栈是按页映射的,而页的大小通常为 4 KB。一旦你读取了大约 1000 个整数,你就已经超过了你应该在的位置大约 4000 个字节,并且你已经越过了一个未映射的页面。从一个未映射的页面中读取是真正触发 seg 错误的原因。

    请注意,我只是在解释您的系统上发生的事情。无法保证堆栈将映射到页面或页面大小为 4 KB。从技术上讲,您正在触发未定义的行为,并且任何事情都可能发生。您可能会发现在每次迭代中执行printf("%p\n", &amp;tab[i]); 并查看在出现段错误之前它打印的最后一个地址是什么很有启发性。如果我对 4 KB 页面的看法是正确的,那么您看到打印的最后一个地址将以 ffc 结尾,因为那将是页面上的最后 4 个字节。

    【讨论】:

      【解决方案3】:

      您正在访问tab 的边界之外,但您仍在自己的堆栈空间中(可能是因为堆栈帧大于一个字节)。您对自己的堆栈具有完全的读/写访问权限。事实上,这就是可能出现许多裂缝的原因。

      当您超出自己的堆栈范围时会发生分段错误。那是您尝试访问不属于您的细分的那一刻(因此称为“细分错误”)。

      【讨论】:

        【解决方案4】:

        越界访问数组将导致未定义的行为。 你在i=1000看到这个

        检查此链接: How dangerous is it to access an array out of bounds?

        【讨论】:

          【解决方案5】:

          超出数组末尾的访问是未定义的行为。 任何事情都可能发生。它可能会工作,它可能会失败,它可能会重新格式化您的硬盘驱动器,或者它可能会发布有关堆栈溢出的问题。

          有时会出现段错误

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-10-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-05-15
            • 1970-01-01
            • 2020-07-26
            • 1970-01-01
            相关资源
            最近更新 更多