指针函数
有些函数是有返回值的,比如int,char... 指针函数就比较特殊了,返回的是一个地址
什么是指针函数:返回指针(地址量)的函数,eg
int* func(inta,intb);
使用举例:
char * strcpy(char *des, const char *src){
char * address = des; //保护原地址
...
return address; //返回的地址来源于外面
}
使用指针函数需注意:内部局部变量地址不能作为返回值
int *func(int a,int b)
{
int value = ...;
return &value;
}
上面的做法是错误的, 我们来做个实验:
#include <iostream>
using namespace std;
int *func(int a,int b)
{
int value;//定义内部局部变量
value = (a>b?a:b);
return &value;//返回局部变量地址
}
int main(int argc, const char * argv[]) {
int a=3,b=4;
cout<<"a和b大的一个值为:"<<*func(a,b)<<endl;
return 0;
}
可以看到,编译器报错了,但是还能输出正确结果,但是真的可以这样做吗?
a和b大的一个值为:4
我们知道所有函数的局部变量都在栈区,栈区是跟随我们的函数周期而存在的。当栈区存在的时候,我们在栈区开辟了局部变量的地址,当栈区结束的时候,函数会把局部变量的地址给回收掉。因此,这里的value是有生命周期的,所以把函数内部地址返回回来是存在一些问题的,因为value只是暂时在这个地址上,不是永久在这个地址上。
所以,貌似返回的是正确的,但是当我们在后面增加一个函数,就会发现问题,改写代码:
#include <iostream>
using namespace std;
int *func(int a,int b)
{
int value;//定义内部局部变量 声明周期非常短
value = (a>b?a:b);
return &value;//返回局部变量地址
}
void say(){
cout<<"hello world"<<endl;
}
int main(int argc, const char * argv[]) {
int a=3,b=4;
cout<<"a和b大的一个值为:"<<*func(a,b)<<endl;
say();
cout<<"a和b大的一个值为:"<<*func(a,b)<<endl;
return 0;
}
可以看到,windows会输出随机值,mac 上的xcode输出正常(但是却报错了)
windows出错的原因分析:当调用say()的时候,func1的内存已经被清空了
怎么修复这个问题呢?换句话说我一定要坚持返回value的地址,怎么做呢?
那么这个value就不能生活在栈区了,我们可以把它放到全局变量中,这时只需加个static
关键字即可