【问题标题】:For loop missing several indexes with segfaultFor 循环缺少几个带有段错误的索引
【发布时间】:2009-06-01 18:15:54
【问题描述】:

应用程序的输出(底部)如下:

元素索引号:0 元素内容:22
元素索引号:1 元素内容:22
元素索引号:2 元素内容:22
元素索引号:3 元素内容:22
元素索引号:4 元素内容:22
元素索引号:22 元素内容:134513712

为什么标记为 5 - 21 的索引元素会丢失?我知道由于数组的边界溢出,这段代码可能会出现段错误,它旨在做到这一点,我对为什么这段代码不好,只是为什么跳过某些索引不感兴趣。

#include <stdio.h>
int main(){

    int array[5];

    int i;
    for(i=0; i<10; ++i) {
        array[i] = 22;
        printf("Element index number: %d Element contents: %d\n", i, array[i]);
    }
    return 0;
}

【问题讨论】:

标签: c for-loop segmentation-fault


【解决方案1】:

一旦您溢出分配的内存,您就处于“未定义区域”。可能是数组写入写入了“i”存储在堆栈中的位置。

请注意,与 Java 和 C# 等语言不同,C 不进行运行时边界检查,因此当您超出数组、字符串或分配的内存时,不能保证执行任何有用的操作(如 segfault)。它不能保证做任何事情。它可能会崩溃,它可能会继续运行,it could cause demons to fly out your nose

【讨论】:

  • 这正是正在发生的事情。 “array”和“i”都存储在堆栈中,“i”紧随“array”之后。所以 &array[5] 指的是与 &i 完全相同的位置。写入数组 [5] 将写入存储在堆栈中 i 位置的值。在您的循环中,当数组溢出时,您将 22 写入 i,因此从 4 跳转到 22。
【解决方案2】:

发生的事情是,当您写入数组 [5] 时,您正在写入 i。它们在内存中与堆栈相邻,因此这是您可以预期的行为。

这样想,你做了一个有 5 个元素的数组

int array[5];

实际上,数组只是一个地址。 [] 中的数字指定要访问该地址多远。所以:

  • array[0] 内存中过去地址“array”的 0 个整数
  • array[1] 是内存过去地址“array”中的 1 个 int ...
  • array[4] 是内存中过去地址“array”的 4 个整数(您为数组保留的最后一个整数)

所以,如果你一路走下去:

  • array[5] 是内存中过去地址“array”的 5 个整数

在 C 中没有自动检查边界,因此很高兴覆盖您自己的内存。您在堆栈中的数组 [5] 之后放置了“i”,很可能数组 [5] 是 i。

您只需将数组 [5] 或 i 设置为 22,因此 i 为 22。现在 i 为 22,您的下一次查找,array[i] 确实是 array[22]。这会抓取内存中该位置发生的任何垃圾,或者如果幸运的话,会崩溃。

【讨论】:

  • "当你写入数组[6] 时,你正在写入 i" 应该是 'array[5]',因为你稍后会正确写入。
  • 请注意,数组结束和 i 开始的位置取决于实现和架构,因此在不同的编译器、不同的操作系统版本、不同的操作系统或不同的架构上,您可能会得到完全不同的结果。
【解决方案3】:

@Doug 有,但让我们稍微扩展一下。

您有 array[5] 和 i 作为自动变量,因此它们在入口处分配在堆栈上,因此您分配了 6 个单元:array[0]、array[1]、... array[4]、然后我。

当您将 i 设置为 5 时,array[i] 指向堆栈中包含 i 的单元格。然后,您将 22 分配给它。所以现在 i=22,就像你打印的那样。

然后你得到array[i] 或array[22],它在stck 的末尾;那里的随机值恰好是那么大的数字。

【讨论】:

  • 说得好。有人的回答需要添加那个细节“然后你得到数组[i]或数组[22]......”
  • 哎呀我刚刚添加了所有这些,不确定我们中的哪一个先说的。 +1 给你
  • 我们穿越了——出于同样的原因,我为你 +1 了。
【解决方案4】:

很可能局部变量“i”的存储位于堆栈上“array”之后,因此 &array[5] == &i,这意味着当您将 22 分配给 array[ 时,您将 22 分配给“i” 5]。

【讨论】:

    【解决方案5】:

    您声明了一个包含 5 个整数的数组,但您的 for 循环将值写入 10 个条目。

    改变

    int array[5];
    

    int array[10];
    

    【讨论】:

    • sorry...downvote,因为您可能甚至没有读过这个问题:...数组的边界被溢出,它旨在做到这一点,我对为什么这样不感兴趣代码不好...
    猜你喜欢
    • 2014-03-22
    • 1970-01-01
    • 2021-12-20
    • 2020-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    相关资源
    最近更新 更多