【问题标题】:I get an unexpected outcome for square array?我得到方阵的意外结果?
【发布时间】:2016-05-20 12:39:19
【问题描述】:

我得到正方形的结果

squares = [ 512, 1, 4, 9, 16, 25, 36, 49 ]

我知道我已经达到了我的极限,但 512 是从哪里来的?您能否解释一下发生错误所涉及的所有单个步骤?

int main()
{
    unsigned squares[8];
    unsigned cubes[8];
    for (int i = 0; i <= 8; i++) {
        squares[i] = i * i;
        cubes[i] = i * i * i;
    }
}

【问题讨论】:

  • 当你写 cubes[8] 时,你实际上是在写 squares[0],因为数组在内存中的布局方式。
  • 哦,好的,谢谢,谢谢。
  • 查看我的回答以了解为什么没有正确回答未定义行为问题。

标签: c arrays loops unsigned


【解决方案1】:

我会说和大家说的一样的话。这是undefined behavior,你不应该那样做。

现在,您会问未定义的行为是否是发生任何事情的原因。

我会说,是的,可能。


现在,您可能认为这很容易避免回答问题。

可能是,但是..

这类问题的主要问题是,很难重新创建相同的案例并调查究竟是什么让它如此行事。因为未定义的行为,嗯,行为方式非常未定义。

这就是人们不尝试回答这类问题的原因,人们建议远离未定义行为领域。

【讨论】:

    【解决方案2】:

    我知道我已经达到了极限

    那么你应该也知道后果。访问越界内存调用undefined behavior

    保持在有效内存限制内。使用

    for (int i = 0; i <8; i++) 
    

    【讨论】:

    • 所以它随机给了512?
    • @PrinceofPersia 是的,它是 UB。 不要那样做
    【解决方案3】:

    你正在访问超出限制的内存

    for (int i = 0; i <= 8; i++) 
    

    应该是

    for (int i = 0; i <8; i++) 
    

    记住unsigned squares[8]; 允许您合法 访问squares[0] 直到squares[7]

    我知道我已经达到了极限,但是 512 是从哪里来的 来自。

    根据 ISO/IEC 9899:201x 6.5.10->fn109

    未定义非法内存访问的后果

    两个对象在内存中可能是相邻的,因为它们是相邻的 较大数组的元素或结构的相邻成员,没有 它们之间的填充,或者因为实现选择放置 他们是如此,即使他们是无关的。如果先前的无效指针 操作(例如访问数组边界外)产生未定义 行为,随后的比较也会产生未定义的行为


    您可以使用调试器(例如 gdb)或检测框架(例如 valgrind)来查找值的来源。这里 512 看起来像 8 的立方,但不能保证下次运行时会得到相同的值。而且,程序有可能会崩溃。

    【讨论】:

    • 是的,我知道,但是出于更好地理解程序的好奇心,512 是从哪里来的。
    猜你喜欢
    • 1970-01-01
    • 2021-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多