当前位置: 首页 > news >正文

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; 
}
http://www.dtcms.com/a/303013.html

相关文章:

  • Linux系统Centos7 安装mysql5.7教程 和mysql的简单指令
  • JVM 内存模型深度解析:原子性、可见性与有序性的实现
  • FFmpeg 安装与使用
  • 从JPEG到SER:小波+CNN如何横扫CVPR/ICASSP?
  • C#_索引器
  • 最新!Polkadot 更新 2025 路线图
  • 【C++】priority_queue的模拟实现
  • Tchebycheff变换简介
  • 应急响应案例处置(下)
  • Dify-14: 工作流API端点
  • gRPC 为 Sui 上更智能的数据访问奠定基础
  • 【Kubernetes】使用StatefulSet进行的资源调度,删除更新策略
  • Linux 应用程序组成
  • haproxy原理及实验演示(实现服务器集群的负载均衡)
  • 火线、零线、地线
  • 雷达系统设计学习:自制6GHz FMCW Radar
  • C++中std::variant的使用详解和实战代码示例
  • 三角洲摸金模拟器(简易版本)(开源)
  • 黑马JavaWeb【复习到哪更新到哪】
  • Coze Studio概览(二)
  • 【MySQL基础篇】:MySQL常用数据类型的选择逻辑与正确使用
  • Go语言-->变量
  • 【Practical Business English Oral Scene Interpretation】在职日常交流No.1~6
  • MySQL面试题及详细答案 155道(001-020)
  • 重构企业交互逻辑:云蝠智能 Voice Agent 的落地价值与实践指南
  • 设计模式(二十一)行为型:状态模式详解
  • 常见的未授权访问漏洞靶场-练习教程
  • MCP架构:模型上下文协议的范式革命与工程实践
  • 安宝特新闻丨安宝特与Logivations正式建立合作伙伴关系,共筑物流新未来
  • OpenLayers 综合案例-区域掩膜