6

程序何时会在缓冲区溢出情况下崩溃

#include<stdio.h>
#include<stdlib.h>

main() {
    char buff[50];
    int i=0;
    for( i=0; i <100; i++ )
    {
        buff[i] = i;
        printf("buff[%d]=%d\n",i,buff[i]);
    }
}

分配的前 50 个字节会发生什么情况,程序什么时候会崩溃?

我在带有 gcc a.out 的 UBUNTU 中看到它在我 99 时崩溃

>>
buff[99]=99
*** stack smashing detected ***: ./a.out terminated
Aborted (core dumped)
<<

我想知道为什么在 for 循环中的 buff[51] 处发生分配时这不会崩溃?

4

2 回答 2

13

这是未定义的行为。您永远无法预测它何时(或是否会)崩溃,但您不能依靠它“不崩溃”来编写应用程序。

推理

基本原理是在 c 数组中没有编译或运行时“索引越界检查”。这存在于其他高级语言的STL 向量或数组中。因此,每当您的程序访问超出分配范围的内存时,这取决于它是简单地破坏程序堆栈上的另一个字段还是影响另一个程序的内存或其他东西,因此永远无法预测仅在极端情况下发生的崩溃。它只会在强制操作系统干预的状态下崩溃,或者当您的程序不再可能正常运行时崩溃。

例子

假设你在一个函数调用中,紧挨着你的数组是返回地址,即你的程序用来返回调用它的函数的地址。假设您损坏了它,现在您的程序尝试返回损坏的值,该值不是有效地址。因此,它会在这种情况下崩溃。

当您默默地修改另一个字段的值并且假设没有发生崩溃时甚至没有发现问题所在时,最糟糕的情况就会发生。

于 2013-10-10T10:50:57.250 回答
1

由于您似乎已经在堆栈上分配了缓冲区,因此应用程序可能会在您第一次覆盖要执行的指令时崩溃,可能在 for 循环的代码中的某处......至少它应该是这样的理论上。

于 2013-10-10T10:53:36.310 回答