我们知道,在c语言中,局部变量与方法被调用时分配的空间是在栈这种数据结构里的,那么,在进行内存的创建与销毁时,就难免会遇到内存空间地址冲突所导致的bug,例如在下面这段代码中,创建了一个空间大小为10的数组,但是在进行数组元素访问时,由于循环的索引过大,从而导致了野指针出现的问题:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main() {
int i = 0;
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
for (i = 0; i <= 12; i++) {
arr1[i] = 0;
printf("hehe\n");
}
return 0;
}
但是运行的结果却造成了程序的死循环:
这是为什么呢?
其实在分配局部变量空间时,栈的地址是由高向低地址进行分配的,编译器通常不会将每个变量的内存空间紧挨着放进内存,而是间隔一段空间存放下一个元素,例如VS2022,而数组开辟空间之
后,数组元素的地址又是由低向高依次增长的。
当for循环内部将数组元素的初始值全部置为0时,循环条件依旧满足,此时再继续下去的话,便会导致溢出, 但是由于栈预开辟的内存未满,程序依旧会执行下去。
此时我进行调试,发现编译器不仅将数组元素的值置为全0,而且将与数组相邻的空间的值也置为0,由于局部变量i在进行第12次循环时,指针arr1[12](一个未初始化但是逻辑上存在的数组元素)的地址与i的地址指向了同一块内存单元。
此时,arr1[12]与i同时赋值为0,导致循环条件一直满足,程序将死循环地执行下去。
当然,这种情况非常依赖编程环境,因为不同的编译器为变量分配 的内存情况不尽相同,所导致的结果也是不一样的。只能说,在进行这种产生异常的代码程序中,死循环在理论上时有出现。