【问题标题】:Array memory allocation [closed]数组内存分配
【发布时间】:2012-03-23 23:24:48
【问题描述】:

这是一个编码站点的问题......

替换“?”使用整数,因此输出为 4。

int main()
{
    int arr[7];
    int b,c,d,a;
    a=4;
    printf("%d",arr[?]);
    return 0;
}

我试图弄清楚这一点,发现答案是-4。 现在,如果我再声明一个变量(如代码第 4 行中的 int b,c,d,e,a),答案是 -5。

请有人解释一下编译器的行为以及内存分配的原因(负索引)。

【问题讨论】:

  • 对此没有有效的答案 - 您可能能够找到一个给出所需结果的值,但它将是编译器特定和体系结构特定的,并且将依赖于未定义的行为
  • 你还没有初始化arr所以你永远不知道!
  • 问你这个问题的人不懂C编程。
  • @another.anon.coward:他不需要。他正在寻找的值不在数组中,他依靠 C 缺乏数组绑定检查来获取a。这是非常糟糕的,除非它是Exploiting Bugs 101的一部分,否则无论谁提出问题都需要被枪决。

标签: c arrays memory allocation


【解决方案1】:

首先,请注意:切勿编写任何依赖于这种行为的代码,因为它会因编译器而异。

编辑:由于第一段显然不够清楚:越界访问数组是未定义的行为,这意味着编译器可能会生成一个程序来执行编译器选择的任何操作。在这里,我正在解释发帖者的编译器可能选择做什么,但也可能是结果偶然变为 4。

您的编译器显然选择了如下布局变量(假设第一个变量最终位于地址 100):

  • 100:a
  • 104:d
  • 108:c
  • 112:b
  • 116:arr[0]
  • 120:arr[1]
  • ...
  • 140:arr[6]

由于arr 从 116 开始,并且其每个元素 (int) 的大小为 4 个字节,arr[-4] 为 116 + 4 * (-4) = 100,这就是 a 的位置位于。

【讨论】:

  • 这是未定义的行为,编译器不能保证从这段代码中给出任何合理的输出,并且允许程序崩溃和烧毁。你不能越界访问数组,就这么简单。
  • 据我们所知,编译器可能也没有这样做。也许在内存位置 arr[-4] 有一些随机的 4,它只是点击了这里。这也是可能的吧?但是,另一方面,如果编译器不会按照您建议的方式放置变量,是否会有任何例外?只是好奇想知道。谢谢
  • @Lundin,真的吗?这是未定义的行为?通过阅读其他 10 个 cmets 陈述相同的事情,无法猜到它!盖伊只是想提出一个最有可能发生的案例。
  • @Lundin:您可以做到这一点,正如 OP 的代码所示,并且由此产生的未定义行为仍然是某种行为,这可能在编译器中有解释选择了做。正如 skynorth 所说,我只是在解释可能发生的事情。
【解决方案2】:

C 不检查数组边界。这意味着您可以使用索引,使您正在使用的内存位置不属于为数组分配的内存。

当你这样做时,你正在访问内存中的其他位置。在本例中,为int变量bcda保留了以下4个位置

所以,您从数组中进入变量空间。

无论如何,它可能取决于编译器/架构,但我希望正确答案是 11(数组的大小 + 4 个变量)

【讨论】:

  • 哦,其他 cmets 都是真的。这本质上是不安全的,您可以在 C 中执行此操作的唯一原因是因为它假定您不会执行此操作,因此程序不会检查值(因此它会变得更快一些)。永远不要使用像 IRL 这样的代码
猜你喜欢
  • 2011-12-15
  • 2020-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-23
  • 2013-12-09
  • 2023-03-15
相关资源
最近更新 更多