C++ 动态内存分配和智能指针 share_ptr/unique_ptr

2023-05-16

目录

1、动态对象以及new/delete

2、智能指针


1、动态对象以及new/delete

C++除了在代码编译时创建的自动(auto)和静态(static)对象外,还支持运行过程中动态分配对象,动态对象只有显式地被释放时,这些对象才会销毁。

C++中使用 new/delete 运算符完成动态内存管理,new在动态空间中为对象分配空间并返回指向该对象的指针,delete接受一个动态对象指针,销毁该对象,并释放与之关联的内存。传递给delete的指针必须指向动态分配的内存,或者是一个空指针,释放一块非new分配的内存,或者将相同的指针释放多次,其行为是未定义的。

为防止空悬指针的出现(指曾经保存一个对象但现在已经释放的内存,空悬指针引起的程序错误难以调试,delete后的指针就变成空悬指针),delete之后最好用nullptr重置指针。

关于 deletedelete[] 的方法:delete 后加方括号 [] 用于在析构时逐个调用数组中的元素的析构函数完成对象数组的析构。一般来说用于析构由 new[] 分配的内存,如下:

class A{
public:
    int *p;
    A(){
        p = new int[10];
    }
    ~A(){
        delete[] p;
    }
}
// 定义十个A对象的对象指针数组
A *a = new A[10];
// 释放a所指向的内存
delete[] a;

上述代码中每一个类对象在定义一个对象时都会初始化一个指向指定动态分配的内存空间的指针,在析构函数中释放相应的内存空间,因此在释放指向A对象的指针数组时需要使用 [] 来逐个调用数组中对象的析构函数来释放相应的内存。如果 delete 后不加 [] 的话就相当于只调用一次析构函数。

动态对象的正确释放是编程中极其容易出错的地方。为了更安全地使用动态对象,标准库定义了两个智能指针类型来管理动态分配的对象。当一个对象应该被释放时,指向它的智能指针可以确保自动地释放它。

2、智能指针

为了更容易同时更安全地使用动态内存,新的标准库提供了两种智能指针(smart pointer)类型shared_ptr unique_ptr 来管理动态内存,类型定义在 <memory> 头文件中。智能指针的行为类似常规指针,重要区别在于他们可以负责自动释放所指向的对象。shared_ptr 允许多个指针指向同一对象,unique_ptr 则“独占”所指向的对象。

1、shared_ptr

与vector一样,智能指针也是模板,因此创建一个智能指针时,必须提供指针可以指向的类型信息,声明可以类似于:

shared_ptr<string> p1;

shared_ptr支持拷贝(将一个shared_ptr赋给另一个shared_ptr)和赋值(给shared_ptr赋予新值)操作。每个shared_ptr都有一个关联的计数器,通常称为引用计数(reference count。无论何时我们拷贝一个shared_ptr,计数器都会递增,例如用一个shared_ptr初始化另一个shared_ptr时,或将它作为参数传给一个函数以及作为函数的返回值时。当我们给shared_ptr赋予一个新值或是shared_ptr被销毁(如一个局部的shared_ptr离开作用域)时,计数器就会递减。

一旦一个shared_ptr的计数器变为0,他就会自动释放自己管理的对象(通过shared_ptr类的析构函数完成自动释放对象及其关联的内存)。如:

auto r = make_shared<int>(42);  // r指向的int只有一个引用者
r = q; // 给r赋值,令他指向另外一个地址,递增q指向的对象的引用计数,递减r原来指向的对象的引用计数,此时r原来指向的对象已经没有引用者,会自动释放

2、unique_ptr

某个时刻只能有一个unique_ptr指向一个给定对象。当unique_ptr被销毁时,它所指向的对象也会被销毁。

与shared_ptr不同,unique_ptr没有类似make_shared的标准库函数返回一个unique_ptr。当我们定义一个unique_ptr时,需要将其绑定到一个new返回的指针上,类似shared_ptr,初始化unique_ptr必须采用直接初始化形式(注意第三行是个错误的示例):

unique_ptr<double> p1;  // 指向一个double的unique_ptr
unique_ptr<int> p2(new int(42));  // p2指向一个值为42的int
unique_ptr<int> p2 = new int(42);  // 错误!必须使用直接初始化形式

3、weak_ptr

weak_ptr是一种不控制所指向对象生存期的智能指针,他指向由一个shared_ptr管理的对象。将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放。即使有weak_ptr指向对象,对象还是会被释放,因此weak_ptr的名字抓住了智能指针“弱”共享对象的特点。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 动态内存分配和智能指针 share_ptr/unique_ptr 的相关文章

  • 嵌入式工程师 面试题 集-C语言

    预编译 1 什么是预编译 xff0c 何时需要预编译 答 xff1a 预编译又称预处理 就是做些代码文本的替换工作 开头的指令 xff0c 比如拷贝 include 包含的文件代码 xff0c define 宏定义的替换 xff0c 条件编
  • 嵌入式工程师面试题集-MCU_STM32

    一 选择题 1 Cortex M处理器采用的架构是 xff08 D xff09 xff08 A xff09 v4T xff08 B xff09 v5TE xff08 C xff09 v6 xff08 D xff09 v7 2 NVIC可用来
  • 嵌入式工程师面试题集汇总

    主观问题 主观问题 介绍类 请自我介绍 xff1f 为什么不留在xx公司 xff08 为啥离职 xff09 xff1f 你5 10年职业规划是怎样的 xff1f 你还写代码吗 xff1f 从工程师到管理再到工程师你是怎样想的或能承受吗 把你
  • C++解决实际问题 ——a的三次方(accode)

    hello大家好 xff0c 在下 小侠雨落 xff0c 几天不见 xff0c 甚是想念啊 xff01 不说了 xff0c 上标题 a的三次方 咳咳 xff0c 题目描述输入一个整数 a xff0c 输出 a 的三次方 输入格式 一行 xf
  • [CVPR2018]Bottom-Up and Top-Down Attention for Image Captioning and Visual Question Answering

    Bottom Up and Top Down Attention 附 xff1a 论文下载地址 主要贡献 提出了一个新的LSTM组合模型 xff0c 包括了attention LSTM和language LSTM 两个组件 在这个组合模型的
  • python matplotlib绘图总结

    目录 1 画线 a 常规画线 xff1a matplotlib pyplot plot 1 xff09 线的颜色 风格 标记点形状 2 xff09 一图多线 xff0c 并加图例 b 非均匀画线 semilogy c 给特定的点打标签 2
  • mysql now的时间问题

    mysql now 函数调用系统时间不对修正方法 进入mysql命令行 查看时区设置 xff1a show variables like 39 zone 39 select 64 64 time zone 两者保持与系统时间一致 xff0c
  • 【谷粒学院】微信扫码支付(224~238)

    224 项目第十五天内容介绍 225 课程评论实现过程分析 226 课程支付功能需求分析 1 课程支付说明 xff08 1 xff09 课程分为免费课程和付费课程 xff0c 如果是免费课程可以直接观看 xff0c 如果是付费观看的课程 x
  • 故障转移集群搭建高可用文件共享服务器

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言 一 故障转移集群是什么 xff1f 二 什么是仲裁盘 xff1f 三 添加故障转移集群功能 四 故障转移集群的建立 五 配
  • HTTP的报文(详解)

    摘要 我们对于http的了解 xff0c 应该在于 xff0c 我们如果想请求一个资源或者访问一个页面 xff0c 客户端 xff08 我们 xff09 应该向服务器发送一个http请求 xff0c 然后得到响应 xff0c 才能出现我们想
  • Kubernetes部署

    文章目录 1 Kubernetes快速部署1 1 Kubernetes安装要求1 2 安装步骤1 3 准备环境1 4 所有节点安装Docker kubeadm kubelet1 4 1 安装Docker1 4 2 添加kubernetes阿
  • 如何从GitHub克隆带有子模块的仓库,比如FreeRTOS

    情形一 xff1a 首次克隆 git clone recurse submodules git 64 github com FreeRTOS FreeRTOS git 该命令会递归克隆该仓库及所有的子模块 工程目录下的 gitmodules
  • grpc生成go文件命令

    标题 xff1a grpc生成go文件命令 类型 xff1a Golang 内容 xff1a 一 生成tag bp go文件命令 1 protoc go out 61 plugins 61 grpc modules course info
  • Prometheus+grafana监控 k8s集群

    在k8s集群中使用node exporter prometheus grafana对集群进行监控 node exporter组件负责收集节点上的metrics监控数据 xff0c 并将数据推送给prometheus prometheus负责
  • 用IAR给MSP430烧录时出现“Only one MSP-FET ez-FET debugger can be connected to your system during recovery”

    一 问题说明 当安装上IAR软件后 xff0c 新建工程配置好后 xff0c 烧录进MSP430 xff08 我的是MSP430F5529 xff09 中时出现 34 Only one MSP FET ez FET debugger can
  • ConstOS防火墙端口操作

    添加端口 permanent 是永久生效的意思 如果不添加则默认重启后失效 firewall cmd zone 61 public add port 61 3490 tcp permanent 重载端口 firewall cmd reloa
  • 分享学习12864心得

    分享12864显示中文 一 12864基本参数二 代码部分1 得到控制时序2 指令集3 对显示屏写入数据 总结 一 12864基本参数 1 电气参数 电源电压 xff1a VDD xff1a 43 3 0 43 5 5V 显示分辨率 xff
  • pandas 处理excel表格数据的常用方法(python)

    最近助教改作业导出的成绩表格跟老师给的名单顺序不一致 xff0c 脑壳一亮就用pandas写了个脚本自动吧原始导出的成绩誊写到老师给的名单中了哈哈哈 xff0c 这里就记录下用到的pandas处理excel的常用方式 xff08 注意 xf
  • STM32单片机课程自学知识点整理 - 指南版

    课程目录 前言网络课程推荐一 基础知识题外话 xff1a 什么是RISC V xff0c RISC V芯片的发展现状1 原码 补码和反码2 为什么1Byte 61 8bit3 什么是I 2 C4 什么是ICode DCode 系统总线 DM
  • ros与STM32通讯报错:Unable to open port

    设备名称 dev mick 记录学习中遇到的问题 xff0c 以及对应的解决办法 xff0c 免得忘了又要查资料 ros与STM32通讯报错 xff1a Unable to open port ros与STM32通讯报错 xff1a Una

随机推荐

  • Clustering Effect of (Linearized) Adversarial Robust Models

    2021 12 6 第三篇 xff08 NeurIPS 2021 xff09 半精读 原文链接 xff1a Clustering Effect of Linearized Adversarial Robust Models 代码链接 xff
  • Hadoop伪分布式搭建实验的详细操作步骤

    一 建立帐号及更新终端命令 1 1 创建hadoop用户 进入ubuntu系统 打开命令行终端 输入以下语句 创建一个名为hadoop的用户 useradd命令的 m用来指定用户名 s用来指定用户登录时所需的shell文件 sudo use
  • 阿里大佬推荐 Spring源码+Redis+Nginx+MySQL等七篇实战技术文档,

    JVM JVM是Java Virtual Machine xff08 Java虚拟机 xff09 的缩写 xff0c JVM是一种用于计算设备的规范 xff0c 它是一个虚构出来的计算机 xff0c 是通过在实际的计算机上仿真模拟各种计算机
  • 数据库实体关系图(ERD)及其画法

    文章目录 1 什么是ER图 2 什么时候画ER图 2 1 数据库设计2 2 数据库调试2 3 数据库创建和补丁2 4 帮助收集需求 3 ERD符号指南4 概念 逻辑和物理数据模型5 如何绘制ER图 数据库绝对是软件系统不可分割的一部分 在数
  • 基于Ubuntu 20.04 安装 Kalibr 踩坑记录

    小师妹要做相机视觉标定 xff0c 需要制作棋盘格 xff0c 无奈其电脑有些卡 xff0c 对此毫无经验的博主从头开始安装 xff08 此前博主已经安装了ROS环境 xff09 xff0c 如果没有安装ROS环境 xff0c 请参照以下链
  • xavier nx的sd卡系统镜像备份及恢复(非sd卡全盘拷贝,只拷贝实际系统大小)

    1 在主机ubuntu上下载安装gparted xff1a sudo apt install gparted 2 将需要备份的 SD 卡插入读卡器然后插入电脑 xff0c 等待 Linux 读取成功 3 输入sudo gparted启动 g
  • 手把手教你安装ubantu22(详细图文)

    安装平台 xff1a VMware Workstation 16 Pro iso镜像 xff1a ubuntu 22 04 1 desktop amd64 iso 下载连接 xff1a Ubuntu 22 04 1 LTS Jammy Je
  • DataX使用之MongoDB2HDFS

    序 xff1a 本文首先介绍DataX使用 编写配置文件的方式 之MongoDB中的数据导出到HDFS上的一些注意事项 xff0c datax安装没有什么坑 xff0c 所以本文不对此进行详细介绍 xff0c 详细安装过程请自行查看官网 一
  • 进程、线程、协程、并发、并行、IO多路复用

    目录 一 什么是IO操作 二 进程 线程 协程 1 进程是资源分配的基本单位 2 线程是任务调度的基本单位 3 协程 由线程创建并全权负责的小弟 三 并行 并发及其与CPU内核数的关系 1 理解并行与并发的区别 2 进程 线程与CPU核数之
  • webpack看这一篇就够了

    文章目录 今日学习目标1 webpack基本概念 61 61 webpack能做什么 61 61 2 webpack的基本使用2 0 创建项目2 1 解决多次引入资源文件2 2 webpack使用2 3 webpack 更新打包 3 web
  • sumo路由文件(.rou.xml文件)的生成以及关于生成交通流的一些方法

    1 首先准备好一个构建的路网 net xml 文件 这里我所利用的一个路网构造如下 xff1a 2 路由文件 rou xml 文件 可以在netedit里边对路网个各个道路边缘id长度以及相关参数进行配置 xff0c 上述路网经过配置 xf
  • SUMO利用OSM(OpenStreetMap)导出地图生成路网并生成交通流教程(超详细!!!)

    1 进入OSM xff0c 下载地图 OSM链接地址 我这里将输出的地图命名为GDUTmap osm 2 将 osm格式转化成为sumo所接纳的 net xml格式 将从osm上下载下来的GDUTmap osm文件放置在一个文件夹下 不一定
  • Vue2.x和Vue3.x-自定义指令的用法及钩子函数

    Vue2 x 用法 全局注册 Vue directive 指令名 自定义指令生命周期 局部注册 directives 指令名 自定义指令生命周期 使用 v 指令名 属性名 修饰符 61 value值 钩子函数 bind 自定义指令绑定到 D
  • LCD1602液晶使用介绍--(完整版)

    lcd1602 43 c51 介绍 文章目录 LCD1602介绍1602引脚信号说明控制器接口介绍1 基本操作时许 2 状态字说明 3 指令说明RAM地址映射 控制时序图代码实现写入命令写数据 试验例程CGRAM自定义字模 xff08 简易
  • DHT11 温湿度传感器

    文章目录 产品概述 产品概述 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器 xff0c 应用领域 xff1a 暖通空调 xff1b 汽车 xff1b 消费品 xff1b 气象站 xff1b 湿度调节器 xff1b
  • C++ 常见问题集合大汇总

    1 什么是多态 xff0c C 43 43 的多态如何实现 多态就是同一函数名的不同形态 xff0c 提供具有不同行为的接口 xff0c C 43 43 的多态又分为静态多态和动态多态 静态多态 xff08 编译时多态 xff09 通过重载
  • vue使用Antd,FormModel,赋值没有重新验证

    Antd xff0c FormModel xff0c 赋值没有重新验证 vue使用Antd xff0c FormModel xff0c 赋值没有重新验证 vue使用Antd xff0c FormModel xff0c 赋值没有重新验证 习惯
  • 【无标题】

    ZED2标定 一 ZED2相机标定1 首先是安装camera calibration xff0c 直接运行安装命令即可2 运行ZED2相机 xff08 会发布zed2话题 xff09 3 运行 camera calibration4 标定
  • 直播相关讲解 -- 分辨率的解释

    1 分辨率的含义 目前手机普遍一种分辨率为1920 1080 xff0c 即1920像素 1080像素 其中1920 1080的像素 61 2073600 xff0c 即分辨率为2073600 xff0c 即大约200万像素 因为水平方向含
  • C++ 动态内存分配和智能指针 share_ptr/unique_ptr

    目录 1 动态对象以及new delete 2 智能指针 1 动态对象以及new delete C 43 43 除了在代码编译时创建的自动 xff08 auto xff09 和静态 xff08 static xff09 对象外 xff0c