智能指针与动态内存

news2024/9/28 17:33:55

动态内存

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.coloradmin.cn/o/1284086.html

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

相关文章

Jupyter NoteBook未授权访问漏洞

任务一&#xff1a; 复现未授权访问的漏洞 任务二&#xff1a; 利用Jupter Notebook控制台执行系统命令&#xff0c;读取/etc/passwd内容 1.搭建环境 2.new下面直接进入终端&#xff0c;而且也不需要登录&#xff0c;我就直接进入了管理界面 3.直接把指令输入进入&#xf…

5个非常良心好用的软件工具,适合各种场景

​ 本期给大家分享5个非常良心好用的软件工具&#xff0c;适合各种场景&#xff0c;能够高效提升你的学习和办公效率&#xff01; 1.多窗口管理——Multrin ​ Multrin是一款多窗口管理软件&#xff0c;可以将不同的应用程序窗口组合成一个标签页&#xff0c;方便在多任务场景…

无惧泄密:揭秘上海迅软DSE防拷贝大杀器!

对于企事业单位而言&#xff0c;文档的安全保护不仅要从源头上进行&#xff0c;杜绝文档在使用、传播过程中产生的泄密风险&#xff0c;同时也要对文档内容本身进行保护。为防止有心人通过拷贝、截屏、拍照等方式盗窃走重要文档内容信息的情况&#xff0c;天锐绿盾文件防泄密软…

【C++ STL】vector类最全详解(什么是vector?vector类的常用接口有哪些?)

目录 一、前言 二、什么是vector ? &#x1f4a6; vector的基本概念 &#x1f4a6;vector的作用是什么 &#x1f4a6;总结 三、 vector的(一维)定义 四、vector(一维)常用接口的使用 &#x1f4a6;vector的常见构造&#xff08;初始化&#xff09; &#x1f4a6;vector…

Python + Appium框架原生代码实现App自动化测试

Step1&#xff1a;首先介绍下pythonappium的框架结构 如下截图所示 . (1)&#xff1a;apk目录主要放置待测app的apk资源&#xff1b; (2)&#xff1a;config目录主要放置配置文件信息&#xff0c;包含&#xff1a;数据库连接配置、UI自动化脚本中所需的页面元素信息及app启…

python pyaudio实时读取音频数据并展示波形图

python pyaudio实时读取音频数据并展示波形图 下面代码可以驱动电脑接受声音数据&#xff0c;并实时展示音波图&#xff1a; import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation import pyaudio import wave import os import op…

基于ssm 传统文化资源库导览系统-计算机毕设 附源码 63347

ssm 传统文化资源库导览系统 目 录 摘 要 Abstract 第1章 前 言 1.1 研究背景 1.3 系统开发目标 第2章 系统开发环境 2.1 java技术 2.4 SSM框架 第3章 需求分析 3.1 需求分析 3.2 系统可行性分析 3.3 项目设计目标与原则 3.4 系统流程分析 第4章 架…

大学里面转专业介绍

目录 个人情况转专业过程中的经验分享转专业后的学习建议和心态调整转专业后的时间平衡 个人情况 信息科学与工程学院计算机科学与技术专业2019级本科生&#xff0c;曾从物理与微电子科学学院后转入信息科学与技术学院。学习成绩连续三年专业前10% 项目&#xff1a;爬虫项目、…

Shopee过期的折扣活动如何删除?Shopee促销商品如何下架?——站斧浏览器

商家们可以轻松删除虾皮过期活动以及下架促销商品&#xff0c;保持店铺的整洁和顾客的购物体验。那么shopee过期的折扣活动如何删除&#xff0c;shopee促销商品如何下架。 Shopee过期的折扣活动如何删除&#xff1f; 在删除虾皮过期活动时&#xff0c;商家们需要遵循以下步骤…

gitlab高级功能之mirroring - push mirroring(一)

今天给大家介绍一个gitlab很高级也是非常有用的功能 - gitlab的mirroring&#xff0c;你可以将仓库镜像到外部或从外部镜像仓库过来&#xff0c;从而可以实现分支、标签和提交的自动同步。 文章目录 1. mirroring的实现方式2. push mirroring2.1 简介2.2 说明 3. 配置推送镜像3…

行业分析:轻轨行业发展现状及市场投资前景

轻轨是城市轨道建设的一种重要形式&#xff0c;也是当今世界上发展最为迅猛的轨道交通形式。轻轨的机车重量和载客量要比一般列车小&#xff0c;因此叫做“轻轨”。 城市轻轨具有运量大、速度快、污染小、能耗少、准点运行、安全性高等优点。城市轻轨与地下铁道、城市铁路及其…

使用JDBC连接和操作数据库以及myBatis初级入门

JDBC简介和使用 java程序操作数据库的方式有很多种&#xff0c;下面列举一些市面上常用的方式&#xff1a; 从图片分析的知&#xff1a; MyBatis MyBatisPlus 这两个所占的比重比较大。都是用于简化JDBC开发的 JDBC&#xff1a;(Java DataBase Connectivity)&#xff0c;就…

Java开发中一些重要软件安装配置

Java技术栈中重要过程 1、JavaWeb1、开发工具VsCode的安装和使用2、Tomcat服务器3、nodejs的简介和安装4、Vite创建Vue3工程化项目ViteVue3项目的创建、启动、停止ViteVue3项目的目录结构 5、Maven安装和配置 1、JavaWeb 1、开发工具VsCode的安装和使用 1 安装过程 安装过程比…

WEB渗透—反序列化(十一)

Web渗透—反序列化 课程学习分享&#xff08;课程非本人制作&#xff0c;仅提供学习分享&#xff09; 靶场下载地址&#xff1a;GitHub - mcc0624/php_ser_Class: php反序列化靶场课程&#xff0c;基于课程制作的靶场 课程地址&#xff1a;PHP反序列化漏洞学习_哔哩哔_…

【C语言】深入理解C语言中的数学运算和类型转换

文章目录 引言取负运算的奥秘源码探索分析与解读 浮点数运算的精细差异源码分析 精度损失与隐式类型转换精度和除零运算探究float类型和double类型的精度各是多少&#xff08;即十进制有效位的位数&#xff09;&#xff1f;在你的机器上&#xff0c;“负数开方”是如何处理的&a…

pbootcms建站

pbootcms建站 一、下载pbootcms二、安装1、进入宝塔面在网站栏&#xff0c;新建站点&#xff0c;将该址里面文件全部清再将下载的pbootcms上传至该地址。 三、修改关联数据库1、在根目录下/config打开database.php照如下修改这里我使用mysqli数据库。修改并使用自已创建的数据库…

206 反转链表

解题思路可以有两种方法&#xff1a;递归 or 迭代。 \qquad 迭代&#xff1a;通过使用for循环遍历&#xff0c;完成目标。方法直观&#xff0c;容易理解。 \qquad 递归&#xff1a;通过函数调用其自身&#xff0c;完成目标。递归最复杂、最重要的部分就是递归函数的构建&#…

flask web开发学习之初识flask(三)

文章目录 一、flask扩展二、项目配置1. 直接配置2. 使用配置文件3. 使用环境变量4. 实例文件夹 三、flask命令四、模版和静态文件五、flask和mvc架构 一、flask扩展 flask扩展是指那些为Flask框架提供额外功能和特性的库。这些扩展通常遵循Flask的设计原则&#xff0c;易于集成…

电脑发生0x80070002错误,0x80070002错误代码怎么解决

电脑发生0x80070002错误代码是一个常见的问题&#xff0c;它通常与Windows更新或系统文件损坏有关。当你的电脑出现这个错误代码时&#xff0c;在使用电脑时可能会受到影响&#xff0c;因为这可能意味着系统无法正常更新或运行。几天的这篇文章将和大家聊聊0x80070002错误代码怎…

学习UnitTest框架,轻松打造无懈可击的代码!

一、什么是UnitTest&#xff1f; 1、介绍 unittest是Python自带的一个单元测试框架&#xff0c;它可以做单元测试&#xff0c;也能用于编写和运行重复的测试工作。 它给自动化测试用例开发和执行提供了丰富的断言方法&#xff0c;判断测试用例是否通过&#xff0c;并最终生成…