下标超出了数组中的范围

时间:2014-10-01 15:29:56

标签: c loops

这里数组的下标超出范围。

 int a[10], i;
for (i = 1; i <= 10; i++)
a[i] = 0;
printf("India");

输出是一个infinte循环,并且printf语句不会被执行。这是用K N King写的:

当我达到10时,程序将0存储到[10]中。但是[10]并不存在。 所以0在[9]之后立即进入记忆。如果变量i恰好跟随 a [9]在内存中 - 可能就是这种情况 - 然后我将被重置为O.导致 循环重新开始。

任何人都可以解释一下吗?

1 个答案:

答案 0 :(得分:3)

这将形成无限循环的想法是基于关于如何在内存中布置变量的假设。特别是,它假设因为i之后a 定义 ,所以a之后会立即将其分配到内存中。

这肯定不能保证,但同样肯定会发生。如果是,则写入a[10]实际上可能会覆盖i。由于它将0写入不存在的a[10],因此实际上将0写入i。然后当循环中的条件检查i <= 10时,这是真的,所以循环继续 - 并且每次i变为10时,它会立即被之前的覆盖循环条件被评估,因此循环从头开始重新开始。

就C或C ++标准而言,它只是未定义的行为 - 当代码写入数组末尾时可能发生任何。它可能会做某些人所期望的事情,或者可能会做一些完全不同且不相关的事情,而这似乎根本没有意义。编译器可以自由地发出在这种情况下几乎可以执行任何操作的代码(例如,它可以将其诊断为错误,并且根本不发出任何代码)。

要了解可能的符合行为:gcc的早期版本有代码来检测实现定义的行为的特定情况(非常类似于未定义的行为,除了实现必须记录它能做什么)。在这种情况下,记录的行为相当复杂。编译器将尝试按顺序执行以下每个操作(并在第一个成功的位置停止):

  1. run nethack(游戏)
  2. 跑流氓(另一场比赛)
  3. 启动emacs,让它执行一个hanoi模拟塔
  4. 打印出“你正处于一个曲折的小通道的迷宫中,都是一样的。”
  5. 我可能会得到那些有点错误的顺序(这是很长时间之前),但你明白了。结果 nothing 与合理的人可能期望的任何事情有关。