C++11新特性智能指针

news2024/10/23 2:14:36

使用智能指针首先要引用头文件

#include<memory>

内存泄漏

shared_ptr是用来解决c++中内存泄漏的问题

什么是内存泄漏呢

内存泄漏

内存泄漏就是我们从堆区申请的一块空间,没有对这块空间进行释放,导致这块空间既不能被重新利用,也不能被找到。

什么会导致内存内存呢

未释放动态分配的内存

shared_ptr循环引用,引用计数可能永远不会降为0.

虚析构,在继承关系中,编译器会把基类与派生类的构造函数同名,此时析构函数为函数隐藏,只会调用指针类型里的析构函数发生内存泄漏。

内存泄漏会导致很多问题,比如长时间运行,性能变差,程序莫名被挂掉,越界等问题

怎么解决内存泄漏的问题

  1. 使用智能指针,shared_ptr,unique_ptr,可以在对象生命周期结束自动释放
  2. RAII思想,RAII指的就是确保资源在对象构造的时候获得,被析构掉的时候自动释放资源。
  3. 使用工具检测内存泄漏,Valgrind,cppcheck等检测工具。

内存泄漏如何定位

  1. 静态的分析工具,cppcheck,可以在编译阶段检测一些潜在的内存泄漏问题
  2. 动态分析工具,Valgrind在Linux系统上较为常用,
  3. 编写自定义的内存分析器

shared_ptr

shared_ptr是一种引用计数思想,当多个指针指向同一对象的时候,这时候对象的引用计数加一,当对象的引用计数为0的时候说明,没有指针再指向这块内存了,我们就要把这块内存释放掉。

实现shared_ptr

#include<iostream>
#include<memory>
using namespace std;
template<class T>


//实现智能指针
/*
无参构造:传递指针构造,拷贝构造,移动构造,移动赋值
reset()替换对象,销毁对象
operator*()
get()获取原始指针
use_count获得引用计数
*/

class Ref {
	int r_count = 0;
	T* obj = nullptr;
public:
	Ref():{}
	Ref(T* target) :obj(target) {
		r_count++;
	}
	//引用计数加1
	inline void increase() {
		r_count++;
	}
	//引用计数减一
	inline vopid reduce() {
		r_count--;
		if (r_count == 0) {
			delete obj;
			delete this;
		}
	}
	T* get() {
		return obj;
	}
	int getCount() {
		return r_count;
	}

};

template<class T>
class Shared_ptr {
	Ref<T>* ref = nullptr;
public:
	Shared_ptr() = default;
	~Shared_ptr() {
		if (ref)ref->reduce();
	}
	Shared_ptr(T* newP) {
		cout << "构造函数---------" << endl;
		ref = new Ref<T>(newP);
	}
	Shared_ptr(const Shared_ptr& other) {
		cout << "拷贝构造函数---------" << endl;
		this->ref = other.ref;
		if (ref)ref->increase();
	}
	Shared_ptr(Shared_ptr&&other) {
		cout << "移动构造---------" << endl;
		ref = other.ref;
		other.ref = nullptr;
	}
	//给已经存在的对象赋值
	Shared_ptr& operator=(const Shared_ptr& other) {
		cout << "赋值函数---------" << endl;
		if (ref) {
			ref->reduce();
		}
		ref = other.ref;
		if (ref) {
			ref->increase();

		}
		return *this;

	}
	Shared_ptr& operator=(Shared_ptr&& other) {
		cout << "移动赋值---------" << endl;
		if (ref) {
			ref->reduce();
		}
		ref = other.ref;
		other.ref = nullptr;
		return *this;
	}
	void reset(T*target) {
		if (ref)ref->reduce();
		ref = neww Ref<T>(target);

	}
	void reset() {
		if (ref)ref->reduce();
		ref = nullptr;
	}
	T& operator*() {
		return *ref->get();
	}
	T* operator->() {
		if (ref) {
			return ref->get();
		}
	}
	int user_count() {
		if (ref)return ref->getCount();
		else return 0;
	}
};

weak_ptr

weak_ptr指针指向对象的时候,并不会导致对象的引用计数加一,因为weak_ptr是用来检测当前对象的引用计数为多少,用他来获取shared_ptr中的一些信息。查看shared_ptr指向的堆区内存是否被释放掉

weak_ptr用来解决shared_ptr多个对象之间交叉有对方类型的引用,导致引用计数可能永远不会为0的循环引用问题

通常不单独使用,只能和shared_ptr联合使用,

unique_ptr

独享所有权的智能指针,提供了严格意义上的所有权

当该对象被销毁时,会在其析构函数中删除关联的原始指针。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2221230.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

impdp+remap_schema导入后登录报ORA-01017: Invalid Username/password

环境说明&#xff1a;有个11.2.0.4的rac数据库&#xff0c;现需要把USR_OA克隆一份出来做测试&#xff0c;新用户名是TEST_OA&#xff0c;直接是expdp导出用户&#xff0c;再用impdpremap_schema生成TEST_OA&#xff0c; 业务人员使用PLSQL(版本12.0.1.1814) 登录TEST_OA时总…

Python程序设计 内置函数 日志模块

logging(日志) 日志记录是程序员工具箱中非常有用的工具。它可以帮助您更好地理解程序的流程&#xff0c;并发现您在开发过程中可能没有想到的场景。 日志为开发人员提供了额外的一组眼睛&#xff0c;这些眼睛不断关注应用程序正在经历的流程。它们可以存储信息&#xff0c;例…

ShardingProxy服务端分库分表

目录 一、为什么要有服务端分库分表&#xff1f; 二、ShardingProxy基础使用 1、部署ShardingProxy 2、配置常用分库分表策略 三、ShardingSphere中的分布式事务机制 1、什么是XA事务&#xff1f; 2、实战理解XA事务 3、如何在ShardingProxy中使用另外两种事务管理器&a…

【不要离开你的舒适圈】:猛兽才希望你落单,亲人总让你回家,4个维度全面构建舒适圈矩阵

单打独斗的英雄时代已经落幕 抱团取暖才是社会寒冬的良策 自然界中&#xff0c;每个物种都占据着自己的领地和生存空间。 生态位的差异决定了它们的生存方式&#xff0c;一旦离开领地&#xff0c;失去群体的庇护&#xff0c;就会沦为野兽的美餐。 人类社会同样存在隐形圈层…

数仓建模:金字塔原理在数仓建模分析中的应用

目录 1 金字塔原理 1.1 金子塔原理基本原理 1.2 金字塔内部结构 2 如何构建金字塔 2.1 金字塔塔尖构建 2.2 金字塔纵向层次构建 2.3 金字塔横向关系构建 2.3.1 归类分组 2.3.2 逻辑递进 2.4 小结 3 金字塔原理应用 3.1 数仓建模 3.1.1 数仓建模分析方法-自上而下…

OBOO鸥柏:液晶拼接大屏搭载节点盒分布式集中管控控制系统新技术

近年来&#xff0c;随着视频监控、会议系统及展示需求的快速增长&#xff0c;KVM分布式输入输出节点控制系统在各大行业中逐渐成为核心技术。OBOO鸥柏的液晶拼接大屏分布式输入输出节点控制系统&#xff08;WControl&#xff09;&#xff0c;以其创新的技术和卓越的用户体验&am…

在线刷题系统测试报告

一、项目背景 1. 本项目是一个在线刷题系统&#xff0c;灵感来源于力扣和牛客等刷题平台&#xff0c;旨在锻炼自己的代码能力和剖析系统整体结构与各模块之间关系的能力。系统支持用户注册与登录&#xff0c;查看题目列表与题目详情&#xff0c;在线提交代码并提供反馈。 2. 该…

【命令操作】信创终端系统上timedatectl命令详解 _ 统信 _ 麒麟 _ 方德

原文链接&#xff1a;【命令操作】信创终端系统上timedatectl命令详解 | 统信 | 麒麟 | 方德 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于如何在信创终端系统上使用timedatectl命令的详细介绍。timedatectl 是Linux系统中非常实用的时间管理工具&#xff0c;…

JMeter模拟并发请求

PostMan不是严格意义上的并发请求工具&#xff0c;实际是串行的&#xff0c;如果需要测试后台接口并发时程序的准确性&#xff0c;建议采用JMeter工具。 案例&#xff1a;JMeter设置20个并发卖票请求&#xff0c;查看后台是否存在超卖的情况 方式一&#xff1a;一共10张票&…

大数据-177 Elasticsearch Query DSL - 聚合分析 指标聚合 桶聚合

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

Excel重新踩坑3:条件格式;基本公式运算符;公式中的单元格引用方式;公式菜单栏其他有用的功能说明;

0、前言&#xff1a;以下内容是学习excel公式的基础内容。 1、需求&#xff1a;将表格特定区域中数值大小大于等于30&#xff0c;小于等于80的单元格&#xff0c;颜色填充为红色&#xff0c;大于80的&#xff0c;颜色填充为黄色。 新建规则之后也可以通过该功能清除规则。 2、基…

【JavaEE初阶】网络编程TCP协议实现回显服务器以及如何处理多个客户端的响应

前言 &#x1f31f;&#x1f31f;本期讲解关于TCP/UDP协议的原理理解~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 &#x1f386;那么废话不多说…

【重学 MySQL】六十六、外键约束的使用

【重学 MySQL】六十六、外键约束的使用 外键约束的概念关键字主表和从表/父表和子表外键约束的创建条件外键约束的特点外键约束的创建方式外键约束的删除外键约束的约束等级外键约束的级联操作外键约束的示例外键约束的作用开发场景阿里开发规范 在MySQL中&#xff0c;外键约束…

免费开源的微信开发框架

近年来&#xff0c;随着人工智能技术的快速发展&#xff0c;聊天机器人在各个领域得到了广泛的应用。在社交媒体中&#xff0c;自动回复成为了一个流行的功能&#xff0c;让用户可以方便地与机器人进行互动。gewe框架&#xff0c;一个开源的微信聊天机器人框架&#xff0c;实现…

Android 10.0 Camera2 拍照镜像功能实现

1.前言 在10.0的系统rom定制化开发中,在进行camera2的相关拍照功能开发中,在某些时候会遇到拍照照片 左右镜像的问题,就是照片左半边和右半边是反的,所以就需要在拍照的时候保存图片的时候实现 左右镜像功能,接下来就来分析下拍照保存图片的流程 2.Camera2 拍照镜像功能实…

银行数字化转型导师坚鹏:2025年银行开门红8大思考

2025年银行开门红8大思考&#xff1a;与2024年相比有哪些新的变化与不同&#xff1f; 1. ‌员工&#xff1a;从认清现实到重塑信心‌ 经济下行周期开启&#xff0c;叠加外部不稳定、不确定因素增加&#xff0c;让很多员工不适应、不习惯&#xff0c;甚至产生躺平心态。2025年…

信息学奥赛复赛复习18-CSP-J2022-01解密-二分答案、二分找边界、二分时间复杂度、二分求最小

PDF文档回复:20241017 1 P8814 [CSP-J 2022] 解密 [题目描述] 给定一个正整数 k&#xff0c;有 k 次询问&#xff0c;每次给定三个正整数 ni,ei,di&#xff0c;求两个正整数 pi,qi&#xff0c;使 nipiqi、eidi(pi−1)(qi−1)1 [输入格式] 第一行一个正整数 k&#xff0c;表…

leetcode动态规划(十)-0-1背包理论基础(一维数组)

一维dp数组&#xff08;滚动数组&#xff09; leetcode中无纯0-1背包问题&#xff0c;可从卡码网上查看题目46.0-1背包问题 一维数组来源于二维数组&#xff0c;其本质是对一维数组进行压缩了&#xff0c;压缩后需要注意在进行背包容量循环的时候采用后序遍历&#xff0c;而不…

Linux系统基础-进程间通信(3)_模拟实现匿名管道

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 Linux系统基础-进程间通信(3)_模拟实现匿名和命名管道 收录于专栏[Linux学习] 本专栏旨在分享学习Linux的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&a…

强心剂!EEMD-MPE-KPCA-LSTM、EEMD-MPE-LSTM、EEMD-PE-LSTM故障识别、诊断

强心剂&#xff01;EEMD-MPE-KPCA-LSTM、EEMD-MPE-LSTM、EEMD-PE-LSTM故障识别、诊断 目录 强心剂&#xff01;EEMD-MPE-KPCA-LSTM、EEMD-MPE-LSTM、EEMD-PE-LSTM故障识别、诊断效果一览基本介绍程序设计参考资料 效果一览 基本介绍 EEMD-MPE-KPCA-LSTM(集合经验模态分解-多尺…