我最近开始学习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循环越界了。我是故意这么做的。我只是不明白在不同的操作系统和计算机上,这种行为是如何不同的。
除了内存布局的可能性之外,写入[10]的尝试实际上会覆盖i,优化编译器也可能会确定,如果代码没有首先访问不存在的数组元素[10],则i值大于10时无法达到循环测试。
Since an attempt to access that element would be undefined behavior, the compiler would have no obligations with regard to what the program might do after that point. More specifically, since the compiler would have no obligation to generate code to check the loop index in any case where it might be greater than ten, it would have no obligation to generate code to check it at all; it could instead assume that the <=10 test will always yield true. Note that this would be true even if the code would read a[10] rather than writing it.
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.