写入数组末尾的影响[重复]

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&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 而我从来没有给它赋值过")

【讨论】:

以上是关于写入数组末尾的影响[重复]的主要内容,如果未能解决你的问题,请参考以下文章

循环结果不正确

链表访问冲突写入位置

Python将numpy数组写入CSV文件[重复]

二分查找(允许重复元素的有序数组)

LintCode(100)删除排序数组中的重复数字

从字符数组java中“删除”重复空格