一道2016年nice的笔试题引发的思考

简介: 一道2016年nice的笔试题引发的思考

回顾上文:


一个有问题的代码

int main()
{
  int i = 0;
  int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
  for (i = 0; i <=12; i++)
  {
    arr[i] = 0;
    printf("hehe\n");
  }
  return 0;
}
复制代码


执行结果:死循环打印hehe




为了发现问题:打印第几次打印


int main()
{
  int i = 0;
  int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
  for (i = 0; i <=12; i++)
  {
    arr[i] = 0;
    printf("hehe\n");
    printf("第%d次打印\n",i);
  }
  return 0;
}
复制代码

image.pngi不能变为12


调试结果:

image.png

将第数组元素下标为12的值也改成0时,i也恢复为0,所以造成了死循环

**为什么呢?


猜想两个占用同一块空间

->验证

image.png




深入理解上述程序err原因


栈区先使用高地址,再使用低地址. 先定义变量i,所以i在高地址位置,然后再定义数组,二者相隔几个地址未知

arr和i中隔了几个元素是未知的,取决于编译器

image.png



变量和数组相隔距离


VC6.0中: arr和i是紧挨着的
VS2013-VS2019 arr和i中间有两个元素
gcc: arr和i之间放一个元素
复制代码

所以在VC6.0条件下,arr[10],写成i <= 10时就死循环了

如何解释:


i和arr是局部变量,放在栈区,栈区的使用习惯是先使用高地址,再使用低地址
画出栈区内存,上面低地址,下面高地址,先把高地址的空间使用了
i在下面创建,arr在上面创建,
又因为随着数组下标的增长,元素的地址又低到高变化
随着数组下标的越界访问,就可能覆盖循环变量i(二者占用同一块空间)
复制代码


问:当i和arr的创建反过来时:直接报错,不会死循环

因为内存布局发生变化


int main()
{
  int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
  int i = 0;
  for (i = 0; i <=12; i++)
  {
    arr[i] = 0;
    printf("hehe\n");
    printf("第%d次打印\n",i);
  }
  return 0;
}
复制代码


执行结果:报错

注意

程序越界有一个报错的时间点,程序停下来时才报错,死循环了没时间报错

image.png


若改成release版本:

image.png

执行结果:打印13个hehe


在Debug情况下: i确实在数组后面存放, i的地址比数组地址大

image.png


而在Release版本:数组的地址更大   编译器进行了优化了,因为考虑到放后面可能出错

image.png


这也证明了Release版本确实可以优化

相关文章
|
7月前
题目----who is the killer?
题目----who is the killer?
34 1
|
6月前
|
存储 C语言 C++
【C语言刷题系列】水仙花数的打印及进阶
【C语言刷题系列】水仙花数的打印及进阶
|
C语言
【C语言】【典例详解】【刷题】猜名次&&猜凶手【循环练习】
【C语言】【典例详解】【刷题】猜名次&&猜凶手【循环练习】
191 0
|
C语言 C++
C语言刷题系列——7.(洛谷)上学迟到
C语言刷题系列——7.(洛谷)上学迟到
294 0
|
C语言
C语言:猜名次
题目: 5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果: A选手说:B第二,我第三; B选手说:我第二,E第四; C选手说:我第一,D第二; D选手说:C最后,我第三;
|
C语言
【C语言每日一题】猜名次
【C语言每日一题】猜名次
108 0
|
C++
【PAT甲级 - C++题解】1011 World Cup Betting
【PAT甲级 - C++题解】1011 World Cup Betting
61 0
Nice!没有内存就一定不能跑程序吗?看完这篇文章你再下定论
主存(RAM) 是一件非常重要的资源,必须要小心对待内存。虽然目前大多数内存的增长速度要比 IBM 7094 要快的多,但是,程序大小的增长要比内存的增长还快很多。正如帕金森定律说的那样:不管存储器有多大,但是程序大小的增长速度比内存容量的增长速度要快的多。下面我们就来探讨一下操作系统是如何创建内存并管理他们的。
|
C语言
【C语言】寻找两个‘单身狗’数
【C语言】寻找两个‘单身狗’数
【C语言】寻找两个‘单身狗’数
C语言刷题(6)(猜名次)——“C”
C语言刷题(6)(猜名次)——“C”