现象
#include <iostream>
using namespace std;
int main()
{
int arr[5] = {1,2};//未初始化的部分值为0
int brr[5]; //数组中的值为无效值
int crr[] = {1,2,3,4,5,6,7}; //数组个数可以从右往左推导
//int len = 10;
//int drr[len]; windows不可,C99标准是允许的 linux可以
//数组越界
int i;
int drr[10] = {1,2,3,4,5,6,7,8,9,10};
for (i = 0; i <= 10; ++i) {
cout << drr[i] << "\n";
drr[i] = 0;
}
return 0;
}
上面代码在不同的编译器上可能会引起不同的后果,主要是以下两点:
- 在一些比较老的编译器上,由于局部变量入栈后,相邻两个变量之间是挨着的,如果数组出现越界,就会将相邻的变量的值修改掉,造成意想不到的后果;
- 在一些新的编译器,两个连续入栈的局部变量,在栈上的空间不是连续的,比如
int a,b,c
,a和b之间内存不相邻,b和c之间也不相邻,他们之间被其他数据间隔开来,使得我们不容易去修改相邻变量的值。
这张图描绘的是相邻变量之间没有特殊间隔的情况,你可以按照循环一次往下走,当i == 10时,会将arr[10] 置为0,也就是将i 的值又从10置为了0,导致循环无法退出,出现死循环或者崩溃。
当然现代编译器可能不会将两个相邻的变量直接内存相邻,他会在两个变量之间搞个间隔,不过,我们也可以跳过这层数据,试着当i == 10,给i 加一个值试试。
总结
这是在整理以前在大学的学习笔记上时看到的一个问题,感觉挺有意思就记录下来,希望各位读者能得到一些启发。