经典笔(面)试题-程序竟然死循环?

代码如下:

#include <stdio.h>
int main()
{
    int i = 0;
    int arr[] = {1,2,3,4,5,6,7,8,9,10};
    for(i=0; i<=12; i++)
    {
        arr[i] = 0;
        printf("hello bit\n");
    }
    return 0;
}

在VS2013开发环境调试以上的代码,解释以上代码的问题。

分析:

这个代码的结果是 死循环

在Debug版本下,按ctrl+F5运行,会发现是死循环。

 居然是死循环!!!为什么不是直接崩溃呢?既然已经越界访问了为什么还是死循环呢?

别急,下面给你好好分析:

首先,我们按F10逐句调试,同时调出监视窗口,发现执行到i=11都没问题,arr[10],arr[11]都变为0

接着按F10,发现arr[12]和i都变为0

接着执行,发现发现arr[12]和i同步变化

那么这个时候,我们就怀疑此时arr[12]和i在同一地址上。

我们调出内存窗口,从执行到i=1开始查看每次循环后i和arr[12]的地址,发现都是相同的。(地址相同)

所以当执行arr[12]=0时把i也变为0从而造成死循环没有越界报错。 

那么为什么会出现这种情况呢?

1、局部变量i和arr是放在栈区内的。

2、栈区内存的使用习惯是先使用高地址再使用低地址(通俗来说,也就是先定义的变量先进去栈区,后定义的后进来,出去的话就是后定义的先出去)

3、数组元素地址是随着数组下标由低到高变化,由低地址到高地址。

【注意】

1、在vs2013-2019中,i和arr之间空2个元素。

2、在vs6.0中,i和arr之间是空0个元素。

3、在gcc中,i和arr之间空1个元素。

在这个代码中,栈区使用如下:

 因为i和arr之间隔2个元素,所以当arr[9]执行完成之后,arr[10]和arr[11]依然执行,当执行arr[12]时,arr[12]覆盖i的位置,和i的地址一样,所以此时arr[12]有地方变为0,而由于i和arr[12]地址相同,所以他们同步变化,造成死循环。

【注意】

若按照此逻辑将i放在arr后定义则无死循环直接报错!

补充:

在release版本下,相同代码执行,结果如下:

原因:在release版本下,会自动对代码进行优化,避免i和arr[12]的地址相同。 

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值