c/c++ 函数返回指针和引用所引发的问题
1、函数返回指针
以下例子中,返回的指针指向的是一个局部变量 a 的地址,当 funcInt 函数结束时,a 的生命周期也就结束了,a 所占用的内存空间将被释放,此时指针指向的地址不变,但是存储值是一个未知数,再使用这个指针是未定义的行为,可能会导致程序崩溃或者出现其他异常。
#include "iostream"
// 返回int指针地址
int * funcInt(){int a = 101;return &a;
}
int main() {int *pInt = funcInt();std::cout <<"funcInt:" <<*pInt<< std::endl; return 0;
}
打印结果:
funcInt:32760
通过结果可以看出,结果并不是我们期待的值 101
,所以代码这么写是有问题的,也是不安全的行为;
解决方案一:使用 static
使用static 表示将这个变量存储到全局区(static静态区),此时就不受栈区管控,当funcInt 函数执行完成后,数据依然存在,代码如下:
#include "iostream"
// 返回int指针地址
int * funcInt(){static int a = 101;return &a;
}
int main() {int *pInt = funcInt();std::cout <<"funcInt:" <<*pInt<< std::endl; return 0;
}
解决方案一:使用 动态分配内存 new
动态分配的内存空间,手动释放后才会清除数据,代码如下
// 返回动态分配内存的int指针
int * funcIntNew(){int * a = new int(101);// 动态分配的内存空间,手动释放后才会清除数据return a;
}
int main() {int *aNew = funcIntNew();std::cout <<"aNew:" <<*aNew<< std::endl;delete aNew;//动态分配的内存必须手动释放
}
2、函数返回引用
引用和指针是一样的,因为引用其实就是带const的指针,
int & funcInt(){int a= 100;int & a_ref = a;return a_ref;
}int main() {int &i= funcInt();std::cout <<"funcInt:" <<i<< std::endl;
}
打印结果:
funcInt:32760
可以发现,打印的也是不确定的值;并不是我们期待的100
,这是因为 返回的指针指向的是一个局部变量 a 的地址,当 funcInt 函数结束时,a 的生命周期也就结束了,a 所占用的内存空间将被释放,再使用这个指针是未定义的行为,可能会导致程序崩溃或者出现其他异常。
解决方案一:static
// 返回静态变量的引用(安全)
int & funcIntStatic(){static int a= 100;int & a_ref = a;return a_ref;
}int main() {int &i1= funcIntStatic();std::cout <<"funcIntStatic:" <<i1<< std::endl; // 打印结果:funcIntStatic:100
}
错误示范:使用动态分配内存new
// 返回动态分配内存变量的引用(不安全,未释放动态分配的内存空间)
int & funcIntNew(){int *a= new int(100);int & a_ref = *a;//delete a; // 一旦释放,main 函数中获取到的值就不确定了,return a_ref;
}
int main() {int &i2= funcIntNew();std::cout <<"funcIntNew:" <<i2<< std::endl;
}