比特鹏哥调试课之数据的储存与越界访问所带来的后果(包括Debug版本与Release版本)

文章通过一段C语言代码展示了由于栈区局部变量i与数组arr的最后一个元素地址重叠,导致的无限循环问题。在Debug模式下,i在arr之上,数组增长会越界;而在Release模式下,经过优化,i在arr之下,避免了问题。文章探讨了内存布局和数据存储对程序执行的影响。
摘要由CSDN通过智能技术生成

首先有如下代码:

#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++)

{

printf("hehe\n");

arr [ i ] = 0;

}

system("pause");

return 0;

}

以下是此段代码的结果:

由图可见,此段代码的结果为死循环打印hehe,这是因为什么原因呢?

我们可通过调试来发现问题,调试结果如下:

由图片可知,当循环走完十个元素时,arr[]中的元素已经全部被赋值为0,那么当程序继续运行时,arr是否会越界访问第11个元素呢?我们接着往下看

很显然,arr数组进行了越界访问,将第11个元素改为了0,我们接着往下看:

当程序运行到最后一个值12时,再运行一次i++变成13,将不再满足循环,从而跳出循环结束打印。这是我们认为的结果,但事实果真如此吗?我们往下看

我们可以惊奇的发现,当i=12运行过后,i居然被重新赋值为了0。这意味着i将重复以上程序的操作,无限循环直到系统崩溃。这也让我们找到了这份代码哪里出了问题。

到这只是发现了那一步出现了问题,并没有真正找到问题的起因以及解决方法。

我们可以接着往下探寻:

既然arr[12]变为0时,i也同时变为0;那么,我们可以试着取一下i的地址与arr[12]的地址作比较,根据程序运行的结果可知,i与arr[12]的地址相同,这到底又是为什么呢?

这里我们就得提到数据在计算机中的存储:

系统内存分为栈区,堆区和静态区,其中栈区是局部变量存放的地方,如图所示:

栈区的默认使用:

  1. 先使用高地址处的空间,

  1. 再使用低地址处的空间。

而数组随着下标的增长地址由低到高变化,如图所示,从低地址依次向上为arr[1],arr[2]........arr[12],

由图我们可以惊奇的发现,i在栈区中存放的空间正好与arr[12]重叠,因此我们就找到了代码出现问题的原因。(这种情况是偶然出现的)

此代码在Debug与Release版本下的区别:

Debug版本按照代码变量创建的顺序进行存储,因此i的内存空间在arr[]之上,在arr[]向上递增时,会越界出现错误。

Release版本下代码会自动进行优化,默认将i的存储空间放在arr[]存储空间之下,因此当arr[]递增时,并不会越界,代码也不会出现问题。

以上便是本文全部内容,有问题处欢迎各位大佬指正!

  • 32
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值