局部变量栈帧的创建内存机制与死循环出现的底层原理分析

本文通过一个C语言示例解释了数组越界访问如何造成死循环。在循环中,当数组索引超出范围,尽管发生了溢出,但由于栈内存的分配特性,数组元素和局部变量i的地址重叠,导致i也被置为0,使得循环条件始终满足,进而形成死循环。这种情况依赖于具体的编译器和内存管理策略。
摘要由CSDN通过智能技术生成

       我们知道,在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,导致循环条件一直满足,程序将死循环地执行下去。

当然,这种情况非常依赖编程环境,因为不同的编译器为变量分配 的内存情况不尽相同,所导致的结果也是不一样的。只能说,在进行这种产生异常的代码程序中,死循环在理论上时有出现。

 

 

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值