从内存角度分析一个特殊的死循环代码

1.实例分析

相信大家在写代码的过程中遇到过不少报错的情况吧!今天我们就从一个特殊的死循环代码来分析背后的内存使用情况,通过调试的方式来进行问题分析,帮助大家对内存分配有一个更深入的理解

先上代码:

#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 \n");
    }
    return 0;
}

很明显,这个代码出现了数组越界访问的问题。我们在vs编译器上,在debug条件下,x86平台下运行这个代码,就会出现死循环,这是为什么呢?

编译条件

如图,代码出现了死循环

想要分析原因,我们就需要从内存的角度来深入了解

我们启动调试,进行观察:

初始状况下,我们可以观察到,内存为arr数组分配了十个整型大小的空间,而变量i正好与arr数组相差两个整型,此时i为0;

随着for循环的继续,i为9时,数组还没有发生越界行为,按照代码将数组的各个元素都赋值为0:

而当i为10、11时,数组出现了越界访问,并且成功把后两个整型位置的数据赋值为0

问题来了,当i=12时,arr数组访问到了i的地址,并且把i赋值为0

当进行赋值操作后,i的值变为0,重新进入循环,并且每一次i=12时,都会被arr数组赋值为0,所以循环一直进行下去,造成了死循环

2.深层原因解释

基本现象已经解释完了!通过以上对内存的观察,我们发现,当i=12时,arr数组访问到了i的地址,把i赋值为0,于是造成了for循环一直继续,造成死循环,那你可能想问了,为什么是i=12,不是别的值呢?接下来上干货!快拿小本本记好!

1. 栈区内存的使用习惯是从高地址向低地址使用的,所以变量i的地址是较大的。arr数组的地址整体是小于i的地址。
2. 数组在内存中的存放是:随着下标的增长,地址是由低到高变化的。所以根据代码,就能理解为什么是下边的代码布局了。

3.如果是下边的内存布局,那随着数组下标的增长,往后越界就有可能覆盖到i,这样就可能造成死循环的。

那为什么i和arr数组之间恰好空出来2个整型的空间呢?这里确实是巧合,在不同的编译器下可能中间的空出的空间大小是不一样的,代码中这些变量内存的分配和地址分配是编译器指定的,所以不同的编译器之间就有差异了。这个死循环的出现是和环境相关的。

注意:栈区的默认的使用习惯是先使用高地址,再使用低地址的空间,但是这个具体还是要编译器的实现,比如:在VS上切换到X64,这个使用的顺序就是相反的,在Release版本的程序中,这个使用的顺序也是相反的。

3.总结

(1)在实际代码编写中,要尽量避免数组的越界访问,即使没报错,但数组的越界访问可能会带来一些潜在的问题

(2)栈区内存一般从高地址到低地址进行使用,但随编译环境变化可能会有不同

(3)数组内存,随下标变大,地址由低到高

希望你能够通过这篇博客有所收获!!

                                                                                   完                                                                                                                                                                                

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值