我们以VS 2013来举例,关于越界访问在编译器中跑起来是会崩溃的。但是有这样一串代码是关于越界访问没有跑崩溃的问题。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
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;
}
我们观察这个代码,发现for循环内有越界访问,所以这个代码有问题,那么现在提问这串代码跑起来是什么样子(死循环),不是应该崩溃吗?为什么会这样?
一.解释问题
经过调试代码发现arr【12】和 i 的地址相同,这样就导致 i 被赋值为0,然后就一直循环
那么问题来了为什么地址会相同?
这就要讲到栈区
我们知道 i 和 arr 是局部变量,而局部变量是放在栈区上的。
栈区内存的使用习惯是先使用高地址空间,再使用低地址空间。
数组是随着下标的增长,地址由低到高变化。
我们由下图(栈区图)得:
当我们arr 越界访问就有可能访问到 i ,这个时候就导致了上面说的死循环。(只有先定义i ,再定义arr才会出现死循环的这个情况,因为栈区内存的使用习惯是先使用高地址空间,再使用低地址空间。通俗点讲就是先把 i 放进去,再放arr。)
这时候还有个问题,为啥他死循环了但是没有报错,这个明显越界访问了,这是因为代码一直死循环,没有时间停下来,来报错,就比如你一直再吃饭没有时间喝水一个道理。
二.总结
VC6.0h环境——0个整形
gcc——1个整形
VS 2013——2个整形
这个就是编译器的问题,以上是VS 2013的示范。
而这个代码的问题是来源于这一本书————《C陷阱和缺陷》。