【问题标题】:The effects of writing past the end of an array [duplicate]写入数组末尾的影响[重复]
【发布时间】:2012-11-17 23:54:16
【问题描述】:

我发现了一些类似这样的 C++ 代码:

struct Test
{
    int a[128];
    char b[768];
};
 
int main()
{
    Test test;
    for( int i = 0; i < 200; ++i)
        test.a[i] = 1;
    return 0;
}

我意识到这是错误的。但是,我想知道效果如何? 在 GCC 4.3.4 上,Test::b 数组保持不变。这有保证吗?这里发生了什么?

阅读效果一样吗?例如

int main()
{
    Test test;
    for( int i = 0; i < 200; ++i)
        int z = test.a[i];
    return 0;
}

【问题讨论】:

  • 关于这个的许多问题......例如stackoverflow.com/questions/10051782/…
  • 投票以完全重复的方式关闭。如果这真的被认为与其他此类问题不同,那么唯一的其他意见太本地化了。

标签: c++ buffer-overflow


【解决方案1】:

这是未定义的行为,任何事情都可能发生。

除了编译器之外,还有更多变量需要考虑 - 版本、操作系统、硬件、天气、星期几等。

标准规定未定义的行为可能意味着任何事情,因此您不能有任何期望,即使使用相同的编译器也是如此。

例如,如果您在 test.a 之后有一个不同的变量,您可能会遇到访问冲突。或者您可以简单地覆盖该变量。一切顺利。

基本上,在这种情况下,未定义的不是写作部分,而是对

的调用
test.a[i]

i&gt;=128。这是不允许的。

【讨论】:

  • 是否定义是标准中未定义的行为?我现在正在浏览它,但没有找到任何东西。
【解决方案2】:

它是undefined behaviour,如果你写在数组的边界之外,你无法预测会发生什么。

【讨论】:

    【解决方案3】:

    未定义的行为。绝对没有保证,实际上任何事情都可能发生。一个常见的反复无常的说法是,它可以通过电子邮件将 goatse 发送给您的祖母。

    http://en.wikipedia.org/wiki/Undefined_behavior

    实际上,它可能会继续进一步写入Test 对象,尽管b 的开头可能不会紧跟在a 的结尾之后,因为出于对齐目的的填充。

    http://en.wikipedia.org/wiki/Data_structure_alignment

    【讨论】:

      【解决方案4】:

      在 C++ 标准定义的抽象语言 C++ 中,任何事情都可能发生。

      在此编译器定义的具体语言 G++ 4.3.4 中,将发生的具体任何事情是您将覆盖 test.b 的前 288 个元素。

      【讨论】:

        【解决方案5】:

        除了“未定义的行为”之外,实际发生的情况取决于您要覆盖的部分是否被实际使用。如果那块内存没有被使用,它可能会导致错误或崩溃(取决于您是否正在运行任何东西来监控问题)。但是,如果那里有一些数据并且它没有崩溃,它可能会在您的软件中导致级联效应,即依赖于被覆盖部分的另一段代码无法执行。这就是跟踪这些问题如此困难的原因,因为当级联故障发生时,很难找到根本原因而不是可见的症状(“为什么这个变量有一个值 x 而我从来没有给它赋值过")

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-02-13
          • 1970-01-01
          • 2017-06-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-12-30
          • 2014-10-26
          相关资源
          最近更新 更多