我们可以发现以下的这段代码中,数组的下标范围为标0~9,而i的范围为0~12,在for循环中
arr[i]会越界访问arr数组之后的内存空间地址 。
#include <stdio.h>
int main()
{
int i = 0;
int arr[10] = { 0 };
for (i = 0; i <= 12; i++)
{
arr[i] = 0;
printf("哈哈\n");
}
return 0;
}以下着手回答这两个问题:
为什么明明越界访问却不报错?
当程序陷入死循环中,程序就一直没有结束运行状态。
所以当前程序还在正常执行中,当然不会报错:数组越界访问
为什么循环变量i变量明明有循环限制条件,却无法退出循环?
首先想搞清这个问题我们就先需要知道这两个知识点:
1.数组随着下标由低到高,存储数组元素的内存地址也,随之由低地址到高地址;
2.本代码中的arr数组和i变量,都为局部变量。
C语言中局部变量在内存中的栈区存储,
栈区内存开辟空间默认:由从高地址到低地址;
回到本次问题的代码中具体分析:
结合以上两点我们可以画图进行分析:

从上面的图中可知:
变量i开辟的内存空间正好位于数组arr的末尾元素地址的后面,并且间隔两个 arr数组存储元素的类型。
通过这点可知:
总结:当arr数组越界访问时,可能会访问到变量i所存储的地址空间
在本次代码中,变量i的范围为0~12,当
当变量 i等于12时 arr[12]所访问的内存空间就刚好为 i变量所开辟的内存空间。
在for 循环中,arr[i]=0;,就会导致在i==12进入循环中,是变量i的值从12,
变化到0,再次进入for中i++后变量i==1,1<=12,循环判断条件为真,继续
进行for循环。
综上所述:
该代码中的for循环判断条件恒成立为真,for循环陷入死循环。
扩展:
当IDE处在release模式下,该代码不会出现报错,反而会正常运行?
当代码出在release模式下IDE会对代码的底层进行优化,改变变量在内存中开辟空间的位置,从而不会在数组下标越界访问的时候,修改到变量i所在的内存空间。
总结:一图流
