我找到了一些类似这样的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数组不受影响。这有保证吗?这里发生了什么?
阅读效果是否相同? e.g。
int main()
{
Test test;
for( int i = 0; i < 200; ++i)
int z = test.a[i];
return 0;
}
答案 0 :(得分:3)
这是未定义的行为,任何都可能发生。
除了编译器之外,还有更多的变量需要考虑 - 版本,操作系统,硬件,天气,一周中的哪一天等等。
标准认为未定义的行为可能意味着任何事情,所以即使使用相同的编译器,也不会有任何期望。
例如,如果您在test.a
之后找到了另一个变量,则可能会出现访问冲突。或者您可以简单地覆盖该变量。一切顺利。
基本上,这不是在这种情况下未定义的写作部分,而是对
的调用test.a[i]
i>=128
。这是不允许的。
答案 1 :(得分:1)
undefined behaviour
如果你写出数组的外边界,你就无法预测会是什么。
答案 2 :(得分:0)
未定义的行为。绝对没有保证,任何事情都可能发生。一个常见的反复无常的评论是,它可以通过电子邮件将山羊邮寄给你的祖母。
http://en.wikipedia.org/wiki/Undefined_behavior
在实践中,它可能会继续进一步写入Test
对象,但b
的开头可能不会在a
结束后立即跟随填充以进行对齐。< / p>
答案 3 :(得分:0)
在C ++中,C ++标准定义的抽象语言,任何事情都可能发生。
在G ++ 4.3.4中,此编译器定义的具体语言,即将发生的特定任何将覆盖test.b
的前288个元素。
答案 4 :(得分:0)
除了“未定义的行为”之外,真正发生的事情取决于你要覆盖的部分是否实际使用过。如果没有使用那块内存,可能会导致错误或崩溃(取决于你是否正在运行任何内容来监控问题)。但是,如果那里有一些数据并且它没有崩溃,则可能会导致软件中的级联效应,其中依赖于被覆盖部分的另一段代码无法执行。这就是使跟踪这些问题变得如此困难的原因,因为当发生级联故障时,很难找到根本原因而不是可见症状(“为什么这个变量在我永远不会为它分配这种值时具有值x “)