程序死循环展示
我们先来看一段代码。
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;
}
我们在VS2019的环境下编译运行这段代码,运行结果死循环打印hello。
编译器报得警告。
warning C6201: buffer overrun for <variable>, which is possibly stack allocated: index <name> is out of valid index range <min> to <max>
C6201:变量的缓冲区溢出(可能是堆栈分配的):索引名称超出有效索引范围 <最小值> 到 < 最大值>
分析
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 bit\n");
}
return 0;
}
通过代码调试打开内存监视窗口。
我们可以看到, i 的地址是0x00b0f9c4, arr数组的地址是0x00b0f994。
数据在内存中的存储分有三块区域:栈区、堆区和静态区,其中栈区是存放局部变量的。
局部变量 i 和 arr数组存放在栈区中,栈区是先使用高地址,再使用低地址;数组随着下标的增长,地址是由低向高变化。
for循环中, i 的内容是从0,一直增加到12,而 arr数组只有10个空间,每次访问 arr数组 i 号位置时,都会将该位置内容设置为0。
arr数组只开辟了10个 int 类型的空间,但是要访问第11个12个等空间时,因为数据在内存中储存是连续的,即使arr数组没有开辟第11个12个等空间,也是可以访问的,但这是越界访问。
当访问到 arr[12] 时,也会将该位置内容设置为0,而 arr[12] 位置恰好为 i 的位置,即 arr[12] 恰巧将 i 设置为0,for循环的结束条件一直无法满足,无法结束循环,因此造成死循环。
以上是在debug版本下。
在release版本下不会导致死循环,release版本做了优化,将 arr数组放在了变量 i 的前面。
|