为什么不能返回局部变量的地址
1,内存分区
这里要搞清楚这个问题,首先我们要弄清内存的分区,
大家可以参考这两篇文章
C++内存分区
C语言详细内存管理
2、四种变量
所有的数据都有两种类型
一是 数据类型
:即我们的int ,float,double等
二是 存储类型
:总共有4种存储类型的变量
自动变量(auto) 寄存器变量(register)
静态变量(static) 外部变量(extern)
寄存器:CPU的一个挂件,速度是最快的
速度比较:寄存器>内存>硬盘(磁盘)
那这些变量用在哪些地方,在哪些位置有效呢?
3、代码分析
#include <iostream>
using namespace std;
int * add(int x, int y) {
int sum = x + y;
return ∑
}
int * add1(int x, int y) {
int *sum = NULL;
int a = x + y;
sum = &a;
return sum;
}
int main() {
int a = 3, b = 5;
int* sum = NULL;
sum = add(a, b);
add1(a, b);
cout << *sum << endl;
return 0;
//sum=add1(a,b)
//add(a,b);
//cout<<*sum<<endl;
//这里我们先调用add1结果也会出现错误
我们执行这个代码会发现怎么不是8?
3+5不应该是8吗?怎么是这么大一个数字?
这里出现错误的原因就是我们返回了局部变量的地址,
这个sum变量是一个局部变量(即auto自动变量)的有效范围仅限于函数被调用的时候,当add函数调用结束时 调用add函数用到的栈也会被系统回收,所以我们再调用add1函数,就把sum所在地址上的内容覆盖了,改变了原来的值,所以打印出来的就是一个错误的答案
但是系统回收后不一定会对栈进行清理或分配给别的函数使用,如果进程再次调用add函数后,系统暂停执行,没有调用别的函数就不会用到这个栈区,值就不会改变
所谓被系统回收的意思是:这段内存不在给add函数使用,而是给同一进程的其他函数使用
这里我们我们有两种改进方式
一,使用指针返回
#include <iostream>
using namespace std;
int* add1(int x, int y) {
int* sum = NULL;
int a = x + y;
sum = &a;
return sum;
}
int main() {
int a = 3, b = 5;
int* sum = NULL;
sum=add1(a, b);
cout << *sum << endl;
return 0;
}
二,使用静态变量(static)
#include <iostream>
using namespace std;
int *add(int x, int y) {
static int sum = x + y;
return ∑
}
int* add1(int x, int y) {
int* sum = NULL;
int a = x + y;
sum = &a;
return sum;
}
int main() {
int a = 3, b = 5;
int* sum = NULL;
sum=add(a, b);
add1(a, b);
cout << *sum << endl;
return 0;
}
这里我们使用了静态变量后,正确打印结果为8,尽管后面调用了其他函数
这里因为静态变量是在全局静态区,函数调用结束,它的内存没有被释放。