我最近开始学习C语言,我正在上一门以C为主题的课程。我目前正在玩循环,我遇到了一些奇怪的行为,我不知道如何解释。

#include <stdio.h>

int main()
{
  int array[10],i;

  for (i = 0; i <=10 ; i++)
  {
    array[i]=0; /*code should never terminate*/
    printf("test \n");

  }
  printf("%d \n", sizeof(array)/sizeof(int));
  return 0;
}

在我运行Ubuntu 14.04的笔记本电脑上,这段代码没有崩溃。它运行到完成。在我学校运行CentOS 6.6的电脑上,它也运行得很好。在Windows 8.1上,循环永远不会终止。

更奇怪的是,当我将for循环的条件编辑为:I <= 11时,代码只在运行Ubuntu的笔记本电脑上终止。它永远不会在CentOS和Windows中终止。

有人能解释一下内存中发生了什么吗?为什么运行相同代码的不同操作系统会产生不同的结果?

编辑:我知道for循环越界了。我是故意这么做的。我只是不明白在不同的操作系统和计算机上,这种行为是如何不同的。


当前回答

与Java不同,C不做数组边界检查,也就是说,没有ArrayIndexOutOfBoundsException异常,确保数组索引有效的工作留给了程序员。故意这样做会导致未定义的行为,任何事情都可能发生。


对于数组:

int array[10]

索引只在0到9的范围内有效。然而,你正试图:

for (i = 0; i <=10 ; i++)

访问数组[10],将条件更改为I < 10

其他回答

因为你创建了一个大小为10的数组,for循环条件应该如下所示:

int array[10],i;

for (i = 0; i <10 ; i++)
{

目前,您正在尝试使用数组[10]从内存中访问未分配的位置,这导致了未定义的行为。未定义行为意味着您的程序将以不确定的方式运行,因此它可以在每次执行时给出不同的输出。

漏洞存在于以下代码段之间:

int array[10],i;

for (i = 0; i <=10 ; i++)

array[i]=0;

由于数组只有10个元素,在最后一次迭代中数组[10]= 0;是缓冲区溢出。缓冲区溢出是未定义的行为,这意味着它们可能格式化您的硬盘驱动器或导致恶魔从您的鼻子里飞出来。

所有的堆栈变量都是相邻排列的,这是很常见的。如果i位于数组[10]写入的位置,则UB将i重置为0,从而导致未终止循环。

要修复,将循环条件更改为i < 10。

Well, C compiler traditionally does not check for bounds. You can get a segmentation fault in case you refer to a location that does not "belong" to your process. However, the local variables are allocated on stack and depending on the way the memory is allocated, the area just beyond the array (array[10]) may belong to the process' memory segment. Thus, no segmentation fault trap is thrown and that is what you seem to experience. As others have pointed out, this is undefined behavior in C and your code may be considered erratic. Since you are learning C, you are better off getting into the habit of checking for bounds in your code.

错误是在部分数组[10]w/c也是I的地址(int数组[10],I;)。 当数组[10]被设置为0时,I将为0 w/c重置整个循环和 导致无限循环。 如果数组[10]在0-10之间,就会出现无限循环。正确的循环应该是(i = 0;I <10;我+ +){…} int数组[10],我; For (i = 0;I <=10;我+ +) array[我]= 0;

你声明int array[10]表示数组的索引为0到9(它总共可以容纳10个整数元素)。但是接下来的循环,

for (i = 0; i <=10 ; i++)

将循环0到10意味着11次。因此,当i = 10时,它将溢出缓冲区并导致未定义行为。

所以试试这个:

for (i = 0; i < 10 ; i++)

or,

for (i = 0; i <= 9 ; i++)