为什么函数可以返回局部变量,但是不能返回局部变量的地址?

本文解释了为什么函数可以返回局部变量的值,但不能返回局部变量的地址。详细分析了两种不同情况下返回局部变量地址的行为,并阐述了原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1、为什么可以返回局部变量

2、为什么不能返回局部变量的地址

(1) 提出问题

(2) 分析问题


1、为什么可以返回局部变量

int test() {
	int a = 10;
	return a;
}

int main() {
	int b = test();

	printf("%d\n", b);
	return 0;
}

每调用一次函数,编译器就会为这个函数在栈上开辟一块空间,在main函数中声明的局部变量也都在这块空间里,因此在调用main函数的时候,其实也会开辟一块空间。

调用test函数的时候,也会分配一块空间,test函数中的局部变量 a 放在 test函数所在栈空间里。

函数执行完毕或者函数返回的时候,这块空间就会被销毁,test函数返回了 a 的值,其实在返回之前,a 的值先会被保存到一个寄存器中,然后再销毁test函数的栈。

这里说的销毁并不是真的销毁,栈空间是否被使用,其实是通过一对指针 ebp 和 esp 来维护的,ebp 指向起始位置,esp 指向末尾位置,这两者之间的空间是当前程序可以使用的。栈空间的销毁也只是指针的移动而已。

实际上函数所返回的变量的值,其实是原变量的拷贝,因此,我们可以返回局部变量。

2、为什么不能返回局部变量的地址

(1) 提出问题

======================= 第一种情况 =======================

int* test() {
	int a = 10;
	return &a;
}

int main() {
	int* b = test();    //error,编译器不会报错

	printf("%d\n", *b);
	return 0;
}

打印结果如下,打印的结果依然是10,因为保存了 a 的地址,就可以定位到内存上的任意位置,即便是不在 ebp 和 esp 划定的范围内,依然可以访问到。

======================= 第二种情况 =======================

在原本的基础上,新增一句话

int* test() {
	int a = 10;
	return &a;
}

int main() {
	int* b = test();    //error,编译器不会报错

    printf("hello\n");    
	printf("%d\n", *b);    
	return 0;
}

打印结果如下,我们发现打印的结果不是10 了,这是为什么?

(2) 分析问题

在 test函数调用以后,内存中的情况如下

第一种情况下,此时已经保存了变量 a的地址,虽然无法使用变量名直接访问,但是使用地址访问是不受限制的。因此,打印出来的结果是 10

第二种情况下,在打印之前,先调用了printf("hello\n"),printf也是函数,调用时会被分配一块空间,此时旧的test函数的空间会被新的 printf函数的空间 覆盖,后面就无法再访问 变量 a了,因为原本的 空间已经被覆盖了。

因此,函数返回的时候,不能返回局部变量的地址,因为原本的局部变量很可能会被新的空间覆盖导致无法访问到。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值