for循环 数组下标越界导致死循环for循环 数组下标越界导致死循环


如图所示函数,最终for语句会陷入死循环,无法结束。


原因在于:堆栈帧中 a[0]~ a[4] 之后是 i  而 访问a[5]时,其地址也是 i所在的地址

因此当你给a[5]赋值为0的时候,也就给 i 赋值为  0 了。

这个问题的原因就是C在编译的时候,不会对数组下标溢出做检查。

因此以后用类似这样的语句时,一定要注意控制数组下标,不要溢出了。

-----------------------------------------------------------



其汇编代码如下:

for循环 数组下标越界导致死循环

·······

······

····

···

···

··

··

·

然而并不能看懂。


------------------------------------------------------



所以用printf函数显示每个变量所在的内存地址

for循环 数组下标越界导致死循环

然后执行

结果如下:

for循环 数组下标越界导致死循环

每个变量的地址都打印出来,能看出,i的地址确实与a[4] + 4 (即a[5])重复了


-----------------------------------------------------------------------------

【总结】

一开始定义a[5]的时候,内存中为数组a开辟了5个内存空间,

第六个放的是i,地址和a[5](假如有a[5])的话 重复了

因此a[5] = 0 这句表达式 等价于 i = 0;

因此陷入死循环。


-----------------------------------------------------------------

【继续深入】

但是如果修改一下一开始变量定义的顺序

for循环 数组下标越界导致死循环

那么出来的结果为:

for循环 数组下标越界导致死循环

不过要注意,访问了没有定义的数组元素a[5] 

这样的代码肯定是有问题的,只不过输出显示暂时是正常的了。

或者,再定义几个无关变量,

for循环 数组下标越界导致死循环

结果为

for循环 数组下标越界导致死循环

···

···

···

···

将那几个无关变量的地址打印出来

这时候会发现 变量 apple 的地址与 a[5](如果有的话) 重了。

而函数中定义apple的位置恰好在定义a[5]的语句的上面。

看来编译器在进行编译的时候,变量在内存中的存储位置,是按照定义的顺序存放的