【应用C】局部变量的栈空间分配

有时候,在C语言的循环中,如果编程时对边界判断错误,就会带来意想不到的结果,小白在本文中提及一个有趣的C语言问题,此问题并不是小白原创,而是一本编程书的考核内容,小白将其分享到此。


C语言有趣的问题

先看代码:

#include <stdio.h>

int main(void)
{
	int a[10];
	int i;

	for(i = 0; i<=10; ++i)
	{
		a[i] = 0;
	}
	/* .... */
}

这是一段最简单不过的数组初始化代码了,可是因为边界判断错误,导致数组访问越界,运行时出现问题。
Linux环境下,运行程序,结果如下:

出现的结果,直接报出栈粉碎错误,程序奔溃。

win10环境下,运行程序,结果如下:

【应用C】局部变量的栈空间分配_第1张图片

出现的结果,程序一直在运行,并没有奔溃。

对于Linux有保护措施,程序直接奔溃,不容易发现问题。可以从win10的结果中分析,为什么程序会进入死循环??要想完整回答这个问题,需要认识C语言局部变量的栈空间分配。


局部变量的栈空间分配

我们知道,函数局部变量是调用该函数的时候才进行内存分配的,如果有多个局部变量,那么变量的分配应该有一个顺序,C语言对局部变量的分配机制是采用栈的方式,贴出栈的概念图:

【应用C】局部变量的栈空间分配_第2张图片

参考以下文章:
https://blog.csdn.net/qq_19406483/article/details/77511447
在上述代码中,C语言函数中的同类型局部变量,分配顺序就是:顺序局部变量、顺序参数
假设有如下函数:

void fun(int a,int b)
{
	int c;
	int d;
	/* ... */
}

那么调用这个函数的时候,局部变量分配顺序是c、d、b、a,也就是先从上到下顺序分配局部变量,再从右往左(视编译器而定)顺序分配参数。


回答程序进入死循环的问题

现在可以完整回答程序为什么会进入死循环了,按照局部变量的栈空间分配,程序中变量储存顺序如下:

【应用C】局部变量的栈空间分配_第3张图片

对于

	for(i = 0; i<=10; ++i)
	{
		a[i] = 0;
	}

最后的a[10]经过地址计算a+10之后就会指向变量 i 所在的内存,然后赋值为0,于是循环变量 i 又从10变到0,再次开启下一次循环,周而复始,于是出现了死循环。
可以验证这一说法,只需要输出 i 的值查看即可:

	for(i = 0; i<=10; ++i)
	{
		a[i] = 0;
		printf("i=%d\n",i);
	}

gcc运行结果:
【应用C】局部变量的栈空间分配_第4张图片


最后,for循环中应该遵循左闭右开的区间规则,因为非常容易阅读出循环次数,而上述的左闭右闭,阅读的时候还要心算一会儿(10-0+1=11次)。

你可能感兴趣的:(#,应用C,C语言有趣问题,C语言发生死循环,C语言局部变量,栈空间分配,数组越界)