0

我发现一些 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;
}
4

5 回答 5

3

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

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

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

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

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

test.a[i]

i>=128. 只是不允许。

于 2012-11-29T20:02:58.600 回答
1

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

于 2012-11-29T20:03:03.163 回答
0

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

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

在实践中,它可能会继续进一步写入Test对象,尽管由于对齐目的的填充,开始b可能不会在结束后立即跟随。a

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

于 2012-11-29T20:04:25.493 回答
0

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

在此编译器定义的具体语言 G++ 4.3.4 中,发生的具体情况是您将覆盖test.b.

于 2012-11-29T20:13:01.073 回答
0

Aside from the "undefined behavior", what really happens depends on whether the part you're overwriting is actually used or not. If that piece of memory isn't being used, it might cause an error or crash (depending if you're running anything to monitor the issue). However, if there is some data there and it does not crash, it might cause a cascade effect in your software where another piece of code that depends on the overwritten part fails to execute. This is what makes tracking these issues so hard, since when a cascade failure happens it's hard to find the root cause as opposed to the visible symptoms ("Why does this variable have a value x when I never ever assign that kind of value to it")

于 2012-11-29T21:13:15.720 回答