智能指针与动态内存

动态内存

new

placement new 是 C++ 中的一种内存分配方式,它允许在给定的内存地址上构造对象,而不是在默认的堆上分配新的内存。这对于某些特殊的内存管理场景非常有用,例如在特定的内存池中分配对象。

C++11 引入了 "new auto" 语法,它允许你使用 auto 关键字来推断要分配的对象的类型。使用 "new auto" 的语法可以简化代码,特别是在创建复杂的类型或者使用模板时。

    // 使用 new auto 分配整数
    auto* myInt = new auto(42);

    // 使用 new auto 分配浮点数
    auto* myDouble = new auto(3.14);

alignas 是 C++11 引入的一个关键字,用于指定对齐方式。它可以用于变量、类型、结构体、类等,使得相应的对象或结构体成员按照指定的对齐方式进行对齐。

new会考虑struct的对齐信息

delete

不要delete非new返回的内存

智能指针

所有权不清晰 没销毁

解决方法:

share_ptr

常用接口

1. get 函数:

get 函数用于获取指向所管理对象的原始指针。这个原始指针可以用于调用不接受智能指针的函数或与 C 接口进行交互。需要注意的是,get 函数返回的是一个裸指针,它不负责引用计数,也不会影响 std::shared_ptr 的所有权。

    1. unique函数:判断该shared_ptr对象是否独占若独占,返回true。否则返回false。

    1. reset函数:
      • 当reset函数有参数时,改变此shared_ptr对象指向的内存。
      • 当reset函数无参数时,将此shared_ptr对象置空,也就是将对象内存的指针设置为nullptr。

指定内存回收逻辑

C++17和20支持的数组

new数组和delete不匹配现象

C++17和20解决方法

#include<iostream>
#include<memory>

int main(){
    std::shared_ptr<int>x(new int[5]);
    //delete(x.get())
    //C++17做法
    std::shared_ptr<int[]>x2(new int[5]);
    //C++20做法
    auto x3=std::shared_ptr<int[5]>();
    return 0;
}

unique_ptr

常用函数

    1. unque_ptr禁止复制构造函数,也禁止赋值运算符的重载。否则独占便毫无意义。、
    1. unqiue_ptr允许移动构造,移动赋值。移动语义代表之前的对象已经失去了意义,移动操作自然不影响独占的特性。
    1. reset函数:
      • 不带参数的情况下:释放智能指针的对象,并将智能指针置空。
      • 带参数的情况下:释放智能指针的对象,并将智能指针指向新的对象。

unique_ptr要传入del

weak_ptr和循环引用

x,y形成环 循环引用

智能指针实现原理

析构两次的解决方法

auto_ptr:管理权转移

template<class T>
	class auto_ptr {
	public:
		auto_ptr(T* ptr) :_ptr(ptr) {}
		auto_ptr(auto_ptr<T>& ap) :_ptr(ap._ptr) {
			ap._ptr = nullptr;
		}
 
		~auto_ptr()
		{
			if (_ptr) {
				cout << "delete:" << _ptr << endl;
				delete _ptr;
				_ptr = nullptr;
			}
 
 
		}
		T& operator*() {
			return *_ptr;
		}
		T* operator->() {
			return _ptr;
		}
	private:
		T* _ptr;
 
	};

缺陷:auto_ptr的问题:当对象拷贝或者赋值后,前面的对象就悬空了
 C++98中设计的auto_ptr问题是非常明显的,所以实际中很多公司明确规定了不能使用auto_ptr

unique_ptr:防拷贝

template<class T>
	class unique_ptr {
	public:
		unique_ptr(T* ptr) :_ptr(ptr) {}
		unique_ptr(unique_ptr<T>& ap) :_ptr(ap._ptr) {
			ap._ptr = nullptr;
		}
		unique_ptr<T>& operator=(unique_ptr<T>& up) = delete;
	
		~unique_ptr()
		{
			if (_ptr) {
				cout << "delete:" << _ptr << endl;
				delete _ptr;
				_ptr = nullptr;
			}
 
 
		}
		T& operator*() {
			return *_ptr;
		}
		T* operator->() {
			return _ptr;
		}
	private:
		T* _ptr;
 
	};

shared_ptr:引用计数

shared_ptr的原理:是通过引用计数的方式来实现多个shared_ptr对象之间共享资源。
1. shared_ptr在其内部,给每个资源都维护了着一份计数,用来记录该份资源被几个对象共享。
2. 在对象被销毁时(也就是析构函数调用),就说明自己不使用该资源了,对象的引用计数减一。
3. 如果引用计数是0,就说明自己是最后一个使用该资源的对象,必须释放该资源;
4. 如果不是0,就说明除了自己还有其他对象在使用该份资源,不能释放该资源,否则其他对象就成野指针了。
 

template<class T>
	class shared_ptr {
	public:
		shared_ptr(T* ptr) :_ptr(ptr),_pcount(new int(1)) {}
		
		shared_ptr(shared_ptr<T>& sp) :_ptr(sp._ptr),_pcount(sp._pcount)
		{
			
			++(*_pcount);
		}
		shared_ptr<T>& operator=(shared_ptr<T>& sp) {
			if (this != &sp) {
				if (--(*_pcount) == 0) {
					delete _pcount;
					delete _ptr;
				}
				_ptr = sp._ptr;
				_pcount = sp._pcount;
				++(*_pcount);
			}
			return *this;
		}
 
		~shared_ptr()
		{
			if (--(*_pcount)==0&&_ptr) {
				cout << "delete:" << _ptr << endl;
				delete _ptr;
				_ptr = nullptr;
			}
 
 
		}
		T& operator*() {
			return *_ptr;
		}
		T* operator->() {
			return _ptr;
		}
	private:
		T* _ptr;
		int *_pcount;
	};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】递归详解

目录 1.前言2. 递归的定义3. 递归的限制条件4. 递归举例4.1 求n的阶乘4.1.1 分析和代码实现4.1.2 画图演示 4.2 顺序打印一个整数的每一位4.2.1 分析和代码实现4.2.2 画图推演 4.3 求第n个斐波那契数 5. 递归与迭代5.1 迭代求第n个斐波那契数 1.前言 这次博客内容是与递归有关&…

leetcode 876.链表的中间结点

补充上次的环形链表没细讲的快慢指针&#xff08;这三道题现在可以连起来看&#xff09;&#xff0c;希望对你做题思路有帮助 876.链表的中间结点 题目 给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结…

kubernetes监控GPA安装部署

本文在于指导如何对k8s的监控GPA(Grafana&#xff0c;prometheus以及alertmanager)进行安装部署。 1. 介绍 Prometheus 在真正部署Prometheus之前&#xff0c;应了解一下Prometheus的各个组件之间的关系及作用&#xff1a; 1&#xff09;MertricServer&#xff1a;是k8s集群…

面试官:说说synchronized与ReentrantLock的区别

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

【NI-RIO入门】Real Time(实时系统解释)

1.什么是实时系统&#xff1f; 实时系统可以非常精确可靠的执行需要特定时许要求的系统&#xff0c;对于许多工程项目来说&#xff0c;通用操作系统&#xff0c;例如WINDOWS等标准PC上运行测量和控制程序是无法精确控制计时的&#xff0c;这些系统很容易受用户的其他程序、图像…

联想LJ2655DN激光打印机清零方法

随着打印机的使用越来越频繁&#xff0c;需要更换耗材的时候也越来越多&#xff1b;但是更换上新的耗材后&#xff0c;很多用户都会遇到一个问题&#xff0c;就是更换完新的耗材后打印机仍然提示寿命将近&#xff0c;或者无墨粉盒灯情况&#xff0c;这个时候就需要我们对打印机…

关于使用百度开发者平台处理语音朗读问题排查

错误信息&#xff1a;"convert_offline": false, "err_detail": "16: Open api characters limit reach 需要领取完 识别和合成都要有

Win7 旗舰版打开Rustdesk软件提示无法启动程序 ,计算机中丢失api-ms-win-shcore-scaling-|1-1-1.dll

环境: Win7 旗舰版 64位 Rustdesk1.19自编译客户端 问题描述: Win7 旗舰版打开Rustdesk软件提示无法启动程序 ,计算机中丢失api-ms-win-shcore-scaling-|1-1-1.dll "api-ms-win-shcore-scaling-|1-1-1.dll" 是一个系统动态链接库文件,它是Windows操作系统的一…

Selenium 学习(0.16)——软件测试之测试用例设计方法——白盒测试——逻辑覆盖法(语句覆盖和判定覆盖)

写在前面 今天回来有点晚&#xff0c;因为上午给小伙伴们开了个小会&#xff0c;随便说了些什么&#xff0c;结果小伙伴们下班就没急着走&#xff0c;弄点我还有点不好意思提前走了&#xff0c;就略留了一会。其实也没说什么&#xff0c;就是强调工作要抓点紧&#xff0c;8小时…

【Windows下】Eclipse 尝试 Mapreduce 编程

文章目录 配置环境环境准备连接 Hadoop查看 hadoop 文件 导入 Hadoop 包创建 MapReduce 项目测试 Mapreduce 编程代码注意事项常见报错 配置环境 环境准备 本次实验使用的 Hadoop 为 2.7.7 版本&#xff0c;实验可能会用到的文件 百度网盘链接&#xff1a;https://pan.baidu…

ADB命令集锦,一起来学吧

前言 在测试APP时&#xff0c;我们常常会用到adb命令来协助测试&#xff0c;那么adb命令到底是什么&#xff1f;有什么用&#xff1f;怎么用&#xff1f; 今天我就整理了一些工作中常用的adb知识点&#xff0c;希望对大家有所帮助。 ADB学习全攻略 ADB是什么&#xff1f; a…

【STM32】TIM定时器输出比较

1 输出比较 1.1 输出比较简介 OC&#xff08;Output Compare&#xff09;输出比较&#xff1b;IC&#xff08;Input Capture&#xff09;输入捕获&#xff1b;CC&#xff08;Capture/Compare&#xff09;输入捕获和输出比较的单元输出比较可以通过比较CNT与CCR寄存器值&#…

Apache Sqoop使用

1. Sqoop介绍 Apache Sqoop 是在 Hadoop 生态体系和 RDBMS 体系之间传送数据的一种工具。 Sqoop 工作机制是将导入或导出命令翻译成 mapreduce 程序来实现。在翻译出的 mapreduce 中主要是对 inputformat 和 outputformat 进行定制。 Hadoop 生态系统包括&#xff1a;HDFS、Hi…

python提取通话记录中的时间信息

您需要安装适合中文的SpaCy模型。您可以通过运行 pip install spacypython -m spacy download zh_core_web_sm来安装和下载所需的模型。 import spacy# 加载中文模型 nlp spacy.load(zh_core_web_sm)# 示例电话记录文本 text """ Agent: 今天我们解决一下这…

【模电】基本共射放大电路的工作原理及波形分析

基本共射放大电路的工作原理及波形分析 在上图所示的基本放大电路中&#xff0c;静态时的 I B Q I\tiny BQ IBQ、 I C Q I\tiny CQ ICQ、 U C E Q U\tiny CEQ UCEQ如下图( b )、( c )中虚线所标注。 &#xff08; a &#xff09; u i 的波形&#xff08; b &#xff09; i B …

fastapi框架可以自动生成接口文档

安装FastAPI pip install fastapi test1.py from fastapi import FastAPIapp FastAPI()app.get("/") def read_root():return {"Hello": "World"}app.get("/items/{item_id}") def read_item(item_id: int, q: str None):#路由处理…

“打败魔法的永远是魔法”——人类应该如何和ChatGPT相处

GPT 的出现不是偶然的&#xff0c;是必然的! 谈起 ChatGPT 不得不提起 GPT&#xff0c;ChatGPT 是基于GPT 模型开发的一种AI交互智能机器人产品&#xff0c;可完成文案编写、代码编写和信息获取等任务。GPT是生成式预训练模型&#xff0c;主要基于 Transformer&#xff0c;目前…

Spring Bean的生命周期各阶段详解附源码

目录 Bean的生命周期Bean定义阶段Bean实例化阶段Bean属性注入阶段Bean初始化阶段Bean销毁阶段 Bean的生命周期 bean的生命周期&#xff0c;我们都知道大致是分为&#xff1a;bean定义&#xff0c;bean的实例化&#xff0c;bean的属性注入&#xff0c;bean的初始化以及bean的销毁…

华为OD机试 - 仿LISP运算 - 逻辑分析(Java 2023 B卷 200分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#…

C语言数组(上)

# 数组的概念 数组是一组相同类型元素的集合。数组中存放的是一个或多个数据&#xff0c;但是数组中的元素个数不能为零&#xff1b;数组中存放的所有元素&#xff08;数据&#xff09;的类型必须是相同的。 数组分为一维数组和多维数组&#xff0c;多维数组一般比较多见的是二…
最新文章