写入数组末尾的影响[重复]
Posted
技术标签:
【中文标题】写入数组末尾的影响[重复]【英文标题】: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;
【问题讨论】:
关于这个的许多问题......例如***.com/questions/10051782/… 投票以完全重复的方式关闭。如果这真的被认为与其他此类问题不同,那么唯一的其他意见太本地化了。 【参考方案1】:这是未定义的行为,任何事情都可能发生。
除了编译器之外,还有更多变量需要考虑 - 版本、操作系统、硬件、天气、星期几等。
标准规定未定义的行为可能意味着任何事情,因此您不能有任何期望,即使使用相同的编译器也是如此。
例如,如果您在 test.a
之后有一个不同的变量,您可能会遇到访问冲突。或者您可以简单地覆盖该变量。一切顺利。
基本上,在这种情况下,未定义的不是写作部分,而是对
的调用test.a[i]
i>=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 而我从来没有给它赋值过")
【讨论】:
以上是关于写入数组末尾的影响[重复]的主要内容,如果未能解决你的问题,请参考以下文章