第12章:动态内存【C++ Primer 中文版 第五版】阅读笔记 + 源码解析

news/2024/5/1 11:02:31/文章来源:https://blog.csdn.net/qq_43648751/article/details/126686039

动态内存

  • 12.1 动态内存与智能指针
    • shared_ptr类

对象的生存周期

对象类型生存周期
全局对象创建:程序启动时。 销毁:程序结束时。
局部自动对象创建:进入其定义所在的程序块时。 销毁:离开其定义所在的程序块时。
局部static对象创建:第一次使用之前。 销毁:程序结束时。
动态分配对象创建:手动创建。 销毁:手动销毁。

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

对象的内存空间

对象类型内存空间
局部 static 对象静态内存
类 static 数据成员静态内存
全局变量静态内存
类内非 static 对象栈内存
动态分配对象堆内存

分配在静态或栈内存中的对象由编译器自动创建和销毁。
分配在堆内存中的对象由程序来控制。

12.1 动态内存与智能指针

在C++中,动态内存的管理是通过一对运算符来完成的:

  1. new,在动态内存中为对象分配空间并返回一个指向该对象的指针,我们可以选择对对象进行初始化;
  2. delete,接受一个动态对象的指针,销毁该对象,并释放与之关联的内存。

代码演示:使用new 创建对象并进行初始化以及使用 delete 释放对象。

#include <iostream>using namespace std;int main()
{//使用 new 在动态内存中为 int 类型对象分配空间并进行初始化。int* p = new int(10);	cout << *p << endl;//释放内存空间delete p;return 0;
}

运行结果:
使用 new 和 delete

代码演示:内存泄露。

#include <iostream>using namespace std;int main()
{//使用 new 在动态内存中为 int 类型对象分配空间并进行初始化。int* p = new int(10);	cout << *p << endl;//new 申请的动态内存未释放,内存泄漏。//delete p;return 0;
}

代码演示:引用非法内存的指针。

#include <iostream>using namespace std;int main()
{//使用 new 在动态内存中为 int 类型对象分配空间并进行初始化。int* p = new int(10);	delete p;p = nullptr;//new 申请的动态内存已经释放,产生引用非法内存*p = 66;cout << *p << endl;return 0;
}

新标准库(C++11)提供两种智能指针类型来管理动态对象:

智能指针类型区别
shared_ptr允许多个 shared_ptr 指针指向同一对象。
unique_ptr只允许一个 unique_ptr 独占所指向的对象

智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象。
类型所在头文件:#include<memory>

shared_ptr类

智能指针是模板,创建一个智能指针时必须提供指针可以指向的类型。
shared_ptr<string> p1; //shared_ptr 可以指向 string 对象
shared_ptr<vector<int>> p2; //shared_ptr 可以指向 vector<int> 对象

默认初始化的智能指针中保存着一个空指针。
代码演示:默认初始化的智能指针中保存着一个空指针。

#include <iostream>
#include <memory>
#include <string>
using namespace std;int main()
{shared_ptr<string> p1;			 //shared_ptr 可以指向 string 对象if (nullptr == p1){cout << "nullptr == p1" << endl;}else{cout << "nullptr != p1" << endl;}return 0;
}

运行结果:
默认初始化的智能指针中保存着一个空指针
代码演示:智能指针解引用。

#include <iostream>
#include <memory>
#include <string>
#include <vector>
using namespace std;int main()
{shared_ptr<string> p1 = make_shared<string>("helloworld"); //创建shared_ptr指针并生成对象进行初始化cout << *p1 << endl;return 0;
}

运行结果:
智能指针解引用

智能指针作为条件判断:
智能指针指向一个对象,返回 true。
智能指针指向空指针,返回false。

代码演示:

#include <iostream>
#include <memory>
#include <string>
#include <vector>
using namespace std;int main()
{shared_ptr<string> p1;			 //shared_ptr 可以指向 string 对象if (p1){cout << "nullptr != p1" << endl;}else{cout << "nullptr == p1" << endl;}return 0;
}

运行结果:
智能指针为空指针返回false,否则返回true
shared_ptr和unique_ptr都支持的操作

p->mem 等价于 (*p).mem

代码演示:

#include <iostream>
#include <memory>
#include <string>
#include <vector>
using namespace std;int main()
{shared_ptr<string> p1 = make_shared<string>("helloworld"); //创建shared_ptr指针并生成对象进行初始化if (!p1->empty()){cout << *p1 << endl;}if(!(*p1).empty()){cout << *p1 << endl;}return 0;
}

运行结果:
p->mem 等价于 (*p).mem

说明:返回 p 中保存的指针。
注意:智能指针释放,p.get() 返回的指针所指向的对象也消失。

代码演示:

#include <iostream>
#include <memory>
#include <string>
#include <vector>
using namespace std;int main()
{string* p2 = nullptr;if (p2){cout << "p2 = " << *p2 << endl;}else{cout << "nullptr = p2" << endl;}{shared_ptr<string> p1 = make_shared<string>("helloworld"); //创建shared_ptr指针并生成对象进行初始化string* p2 = p1.get();if (p2){cout << "p2 = " << *p2 << endl;}else{cout << "null = p2" << endl;}//智能指针释放,p.get() 返回的指针所指向的对象也消失。}if (p2){cout << "p2 = " << *p2 << endl;}else{cout << "nullptr = p2" << endl;}return 0;
}

运行结果:
p.get()

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

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

相关文章

软件设计师笔记-----系统安全分析与设计

五、系统安全分析与设计 5.1、信息系统安全属性 安全属性包括 保密性&#xff1a;最小授权原则、防暴露、信息加密、物理保密完整性&#xff1a;安全协议、校验码、密码验、数字签名、公证可用性&#xff1a;综合保障&#xff08;IP过滤、业务流控制、路由选择控制、审计眼踪…

复习单片机:定时器/计数器部分(内含:1.51 单片机定时器原理 +2.51 单片机定时/计数器结构+3.定时器配置+4.代码部分+5.实验现象)

1.51 单片机定时器原理STC89C5X 单片机内有两个可编程的定时/计数器 T0、T1 和一个特殊功能定 时器 T2。定时/计数器的实质是加 1 计数器&#xff08;16 位&#xff09;&#xff0c;由高 8 位和低 8 位两 2个寄存器 THx 和 TLx 组成。 它随着计数器的输入脉冲进行自加 1&#x…

初识kotlin(初用kotlin一时爽、一直用一直爽)

kotlin历程 2011年7月&#xff0c;JetBrains推出Kotlin项目&#xff0c;这是一个面向JVM的新语言2012年2月&#xff0c;JetBrains以Apache 2许可证开源此项目2016年2月15日&#xff0c;Kotlin v1.0发布。这被认为是第一个官方稳定版本&#xff0c;并且JetBrains已准备从该版本…

【云原生】zookeeper + kafka on k8s 环境部署

文章目录一、概述二、Zookeeper on k8s 部署1&#xff09;添加源2&#xff09;修改配置3&#xff09;开始安装4&#xff09;测试验证5&#xff09;Prometheus监控6&#xff09;卸载三、Kafka on k8s 部署1&#xff09;添加源2&#xff09;修改配置3&#xff09;开始安装4&#…

pytorch线性代数的基本操作

线性代数的基本操作 标量由只有一个元素的张量表示 import torch xtorch.tensor([3.0]) ytorch.tensor([2.0]) xy,x*y,x/y,x**y向量视为标量值的组成 通过张量的索引来访问任一元素 xtorch.arange(4) x,x[3] #张量的长度 len(x) #张量的形状 x.shape对称矩阵 AAT Btorch.ten…

一文看懂线性回归(保姆级别 含源码)

来源: AINLPer 微信公众号&#xff08;每日论文干货分享&#xff01;&#xff01;&#xff09; 编辑: ShuYini 校稿: ShuYini 时间: 2022- 9 -18 引言 最近作者网上看了很多关于线性回归的帖子&#xff0c;个人感觉比较乱&#xff0c;所以打算自己整理一版&#xff0c;希望能把…

(41)STM32——外部SRAM实验笔记

目录 学习目标 成果展示 硬件知识 特点 功能框图 读时序 ​编辑写时序 FSMC驱动 寄存器 闪存片选控制寄存器 硬件 配置 代码 总结 学习目标 今天我们要学习的是有关外部SRAM实验&#xff0c;其实F&#xff14;内部也是有一个&#xff11;&#xff19;&#x…

本周大新闻|索尼PS VR2体验首次公开;Meta Quest Pro开箱视频曝光

本周大新闻&#xff0c;AR方面&#xff0c;沃尔玛App加入AR试穿功能&#xff1b;谷歌搜索AR新增60个行星、卫星模型&#xff1b;Niantic宣布与漫威娱乐合作打造新款LBS AR游戏&#xff1b;AR眼镜ActiveLook打通Apple Watch。 VR方面&#xff0c;索尼PS VR2体验首次公开&#x…

2022年笔试知识总结展望

应届生的笔试知识总结&#xff0c;温故而知新&#xff0c;看看知识加深印象&#xff0c;希望学得更好&#xff0c;有个好结果。 目录 1. TCP的拥塞控制 2. position属性 3. [‘1‘, ‘2‘, ‘3‘].map(parseInt) 输出结果 4. 排序算法的稳定性分析 1&#xff09;稳定的排…

事件研究法与其应用(2)---Excel实操步骤

我们借着学习事件研究法的应用,可以用Excel和Stata等软件进行操作。 今天这主要是利用EXCEL计算累积异常收益率。 在正式开展实操之前,我们先回顾一下事件研究法的步骤(尤其是我们写作论文的时候): 事件研究法计算步骤: 1. 获取数据,定义事件期 2.计算估计期间个股与市…

npm yarn 报错

目录npm yarn报错yarn: 无法加载文件 npm yarn报错 yarn: 无法加载文件 win10系统,yarn : 无法加载文件 C:\Users\丽丽小可爱\AppData\Roaming\npm\yarn.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 ... 导致此错误的原因是,PowerShell 执行策略,默认设置为Rest…

JSON 数据类型转换工具

简介 本文介绍一款数据类型转换工具&#xff0c;可以将JSON格式数据转换成YAML、MYSQL、XML、TOML、JavaScript等数据类型。 背景 在日常的开发工程中&#xff0c;我们经常使用JSON表达数据&#xff0c;但有些时候我们需要使用YAML、JavaScript等语言表达数据。因此&#xf…

HTML + HTTP请求 +CSS知识点

文章目录HTML1.HTML元素2.HTML页面3.常见元素1&#xff09;文本2&#xff09;多媒体3&#xff09;表单作用与语法常见表单项案例体验4.HTTP请求1&#xff09;请求组成2&#xff09; 请求方式与数据格式get 请求示例post 请求&#xff08;默认格式&#xff09;示例json 请求&…

Python必知必会 os 模块详解

文章目录Python os 模块os模块的常用操作os.path模块os.open()模块Python os 模块 os是“operating system”的缩写&#xff0c;os模块提供各种 Python 程序与操作系统进行交互的接口&#xff0c;使用os模块&#xff0c;一方面可以方便地与操作系统进行交互&#xff0c;另一方…

【SLAM】4李群李代数

文章目录4.1.基础群李代数的引出李代数李代数so(3)\mathfrak{so}(3)so(3)李代数se(3)\mathfrak{se}(3)se(3)4.2.指数与对数映射4.2.1.SO(3)SO(3)SO(3)指数映射4.2.2.SE(3)SE(3)SE(3)的指数映射4.3.李代数求导与扰动模型4.3.1.BCH公式&近似形式4.3.2.李代数求导4.3.4.扰动模…

redis下载与安装(Linux环境下)

用的是阿里云的深度os Linux系统 一&#xff0c;下载 键入命令&#xff1a; wget http://download.redis.io/releases/redis-6.2.1.tar.gz 检查时候有gcc环境 gcc --version 若有gcc环境会有类似于下图的提示 没有则执行&#xff1a; yum install gcc 下载完毕之后&…

JavaEE基础知识

文章目录前言计算机的基本组成CPUCPU运行程序的过程CPU的构造操作系统操作系统功能常见的操作系统操作系统的具体组成操作系统的进程管理(重点)操作系统安排程序进程PCB(进程管理块)进程调度关于进程的几个属性虚拟地址空间线程(thread [θred] )前言 之前已经学过很多的知识,…

企业薪资系统

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a;

PostgreSQL - 基于pg_basebackup实现主从流复制

PostgreSQL - 基于pg_basebackup实现主从流复制1 数据库节点2 安装PostgreSQL2.1 创建postgres用户2.2 安装PostgreSQL3 配置主节点4 配置从节点5 验证主从同步1 数据库节点 节点ip节点角色192.168.163.133主节点192.168.163.134从节点 2 安装PostgreSQL 2.1 创建postgres用户…

计算机网络——数据链路层(滑动窗口协议: 选择重传)(点对点协议 PPP)

目录 滑动窗口协议: 选择重传 选择重传协议 选择重传协议 点对点协议 PPP PPP 的主要特点 PPP 协议有三个组成部分 PPP 协议的帧格式 PPP 有一个 2 个字节的协议字段 透明传输问题 PPP 的字符填充 PPP 的工作状态 滑动窗口协议: 选择重传 选择重传协议 GBN相对简单&a…