c/c++ 函数返回指针和引用所引发的问题

发布时间:2023-05-10 22:56:54 作者:yexindonglai@163.com 阅读(658)

1、函数返回指针

以下例子中,返回的指针指向的是一个局部变量 a 的地址,当 funcInt 函数结束时,a 的生命周期也就结束了,a 所占用的内存空间将被释放,此时指针指向的地址不变,但是存储值是一个未知数,再使用这个指针是未定义的行为,可能会导致程序崩溃或者出现其他异常。

  1. #include "iostream"
  2. // 返回int指针地址
  3. int * funcInt(){
  4. int a = 101;
  5. return &a;
  6. }
  7. int main() {
  8. int *pInt = funcInt();
  9. std::cout <<"funcInt:" <<*pInt<< std::endl;
  10. return 0;
  11. }

打印结果:

  1. funcInt:32760

通过结果可以看出,结果并不是我们期待的值 101,所以代码这么写是有问题的,也是不安全的行为;

解决方案一:使用 static

使用static 表示将这个变量存储到全局区(static静态区),此时就不受栈区管控,当funcInt 函数执行完成后,数据依然存在,代码如下:

  1. #include "iostream"
  2. // 返回int指针地址
  3. int * funcInt(){
  4. static int a = 101;
  5. return &a;
  6. }
  7. int main() {
  8. int *pInt = funcInt();
  9. std::cout <<"funcInt:" <<*pInt<< std::endl;
  10. return 0;
  11. }

解决方案一:使用 动态分配内存 new

动态分配的内存空间,手动释放后才会清除数据,代码如下

  1. // 返回动态分配内存的int指针
  2. int * funcIntNew(){
  3. int * a = new int(101);
  4. // 动态分配的内存空间,手动释放后才会清除数据
  5. return a;
  6. }
  7. int main() {
  8. int *aNew = funcIntNew();
  9. std::cout <<"aNew:" <<*aNew<< std::endl;
  10. delete aNew;//动态分配的内存必须手动释放
  11. }

2、函数返回引用

引用和指针是一样的,因为引用其实就是带const的指针,

  1. int & funcInt(){
  2. int a= 100;
  3. int & a_ref = a;
  4. return a_ref;
  5. }
  6. int main() {
  7. int &i= funcInt();
  8. std::cout <<"funcInt:" <<i<< std::endl;
  9. }

打印结果:

  1. funcInt:32760

可以发现,打印的也是不确定的值;并不是我们期待的100,这是因为 返回的指针指向的是一个局部变量 a 的地址,当 funcInt 函数结束时,a 的生命周期也就结束了,a 所占用的内存空间将被释放,再使用这个指针是未定义的行为,可能会导致程序崩溃或者出现其他异常。

解决方案一:static

  1. // 返回静态变量的引用(安全)
  2. int & funcIntStatic(){
  3. static int a= 100;
  4. int & a_ref = a;
  5. return a_ref;
  6. }
  7. int main() {
  8. int &i1= funcIntStatic();
  9. std::cout <<"funcIntStatic:" <<i1<< std::endl; // 打印结果:funcIntStatic:100
  10. }

错误示范:使用动态分配内存new

  1. // 返回动态分配内存变量的引用(不安全,未释放动态分配的内存空间)
  2. int & funcIntNew(){
  3. int *a= new int(100);
  4. int & a_ref = *a;
  5. //delete a; // 一旦释放,main 函数中获取到的值就不确定了,
  6. return a_ref;
  7. }
  8. int main() {
  9. int &i2= funcIntNew();
  10. std::cout <<"funcIntNew:" <<i2<< std::endl;
  11. }

关键字c++