C语言中,数组越界访问,不报错,直接陷入死循环,IDE环境VS2022,GCC中存在差异。

我们可以发现以下的这段代码中,数组的下标范围为标0~9,而i的范围为0~12,在for循环中

arr[i]会越界访问arr数组之后的内存空间地址 。

#include <stdio.h>


int main()
{
	int i = 0;
	int arr[10] = { 0 };

	for (i = 0; i <= 12; i++)
	{
		arr[i] = 0;
		printf("哈哈\n");
	}

	return 0;
}

以下着手回答这两个问题: 

        为什么明明越界访问却不报错?

                当程序陷入死循环中,程序就一直没有结束运行状态。

                所以当前程序还在正常执行中,当然不会报错:数组越界访问

        为什么循环变量i变量明明有循环限制条件,却无法退出循环?

                首先想搞清这个问题我们就先需要知道这两个知识点:

                        1.数组随着下标由低到高,存储数组元素的内存地址也,随之由低地址到高地址;

                        2.本代码中的arr数组和i变量,都为局部变量。

                            C语言中局部变量在内存中的栈区存储,

                            栈区内存开辟空间默认:由从高地址到低地址;

   

        回到本次问题的代码中具体分析:             

                        结合以上两点我们可以画图进行分析:

                从上面的图中可知:

                        变量i开辟的内存空间正好位于数组arr的末尾元素地址的后面,并且间隔两个                 arr数组存储元素的类型。

                通过这点可知:

                        总结:当arr数组越界访问时,可能会访问到变量i所存储的地址空间

                        在本次代码中,变量i的范围为0~12,当

                        当变量 i等于12时 arr[12]所访问的内存空间就刚好为 i变量所开辟的内存空间。

                        

                        在for 循环中,arr[i]=0;,就会导致在i==12进入循环中,是变量i的值从12,

                        变化到0,再次进入for中i++后变量i==1,1<=12,循环判断条件为真,继续

                        进行for循环。

                综上所述:

                        该代码中的for循环判断条件恒成立为真,for循环陷入死循环。

扩展:

        当IDE处在release模式下,该代码不会出现报错,反而会正常运行?

                当代码出在release模式下IDE会对代码的底层进行优化,改变变量在内存中开辟空间的位置,从而不会在数组下标越界访问的时候,修改到变量i所在的内存空间。

        

总结:一图流

 

 


版权声明:本文为m0_57193668原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。