《C++ Primer 第五版 中文版》第12章 动态内存【阅读笔记 + 个人思考】

《C++ Primer 第五版 中文版》第12章 动态内存【阅读笔记 + 个人思考】

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

静态内存包括:初始化只读数据段,初始化读写数据段,未初始化数据和常量数据段。

详细在下面博客总结:
Linux系统下C++程序运行时的内存布局及存储内容,生命周期,初始化时机详解。

智能指针的作用:一个动态内存空间对象应该被释放时,指向它的智能指针可以确保自动释放它。

12.1 动态内存与智能指针

运算符new:在动态内存为对象分配空间,返回指向该对象的指针。(是否进行初始化可选)

代码演示:当你使用new来分配内存但不提供初始化值时,分配的对象将拥有未定义的初始值(对于基本类型)。如果是类对象,将调用默认构造函数进行初始化。

#include <iostream>int main() {// 为int分配内存,但不初始化,值未定义,访问这些未初始化的值是不安全的int* pInt = new int;// 为double分配内存,但不初始化,值未定义,访问这些未初始化的值是不安全的double* pDouble = new double;// 记得释放内存delete pInt;delete pDouble;return 0;
}

代码演示:使用new时,可以通过在类型后面添加圆括号()或大括号{}来提供初始化值。

#include <iostream>int main() {// 为int分配内存,并初始化为0int* pInt = new int(0);// 为double分配内存,并初始化为0.0double* pDouble = new double(0.0);// 使用列表初始化int* pIntList = new int{10};double* pDoubleList = new double{10.5};std::cout << "*pInt: " << *pInt << "\n";std::cout << "*pDouble: " << *pDouble << "\n";std::cout << "*pIntList: " << *pIntList << "\n";std::cout << "*pDoubleList: " << *pDoubleList << "\n";// 记得释放内存delete pInt;delete pDouble;delete pIntList;delete pDoubleList;return 0;
}

运行结果:
运行结果
详细值初始化和默认初始化参考:值初始化和默认初始化详解

delete:接受一个动态对象的指针,销毁该对象,释放与对象关联的内存空间。

内存泄露:没有释放内存。
引用非法内存的指针:有指针引用内存的情况下释放了内存空间。

(C++11)shared_ptr:共享所指对象。

(C++11)unique_ptr:独占所指对象。

(C++11)weak_ptr :指向 shared_ptr 管理的对象。
参考:有了 unique_ptr 和 shared_ptr,要weak_ptr 有什么用?

头文件 memory。

12.1.1 shared_ptr类

智能指针是模板,默认初始化的智能指针中保存着一个空指针。

解引用智能指针:返回它指向的对象。

条件判断中使用智能指针:检测是否为空。

shared_ptr 和 unique_ptr 都支持的操作:![shared_ptr 和 unique_ptr
shared_ptr 独有的操作:
shared_ptr 独有的操作
最安全的分配和使用动态内存的方法:调用 make_shared 标准库函数(分配对象并初始化,返回指向此对象的 shared_ptr。不传递任何参数,对象进行值初始化。定义在头文件 memory)。

代码演示:

#include <iostream>
#include <memory> // 包含std::shared_ptr及相关函数class MyClass {
public:void classMethod() const {std::cout << "MyClass::classMethod() called" << std::endl;}
};int main() {// 使用make_shared()方法创建std::shared_ptrstd::shared_ptr<MyClass> sp1 = std::make_shared<MyClass>();// 判断shared_ptr是否为空if (sp1 != nullptr) {std::cout << "sp1 is not null" << std::endl;}// 解引用shared_ptr来调用对象的方法(*sp1).classMethod();// 使用->操作符调用对象成员函数sp1->classMethod();// 使用get()方法获取原始指针MyClass* p = sp1.get();std::cout << "Address of the object owned by sp1: " << p << std::endl;// 使用拷贝构造函数创建一个shared_ptr的副本std::shared_ptr<MyClass> sp2(sp1);std::cout << "use_count of sp1 after copying: " << sp1.use_count() << std::endl; // 输出引用计数// 使用赋值操作符std::shared_ptr<MyClass> sp3;sp3 = sp1;std::cout << "use_count of sp1 after assignment: " << sp1.use_count() << std::endl; // 输出引用计数// 使用unique()方法检查当前shared_ptr是否是对象唯一的所有者if (!sp1.unique()) {std::cout << "sp1 is not unique" << std::endl;}// 使用use_count()方法查看对象的引用计数std::cout << "use_count of sp1: " << sp1.use_count() << std::endl;// 使用swap()方法交换两个shared_ptr的内容std::shared_ptr<MyClass> sp4 = std::make_shared<MyClass>();std::cout << "Before swap, sp1 address: " << sp1.get() << ", sp4 address: " << sp4.get() << std::endl;sp1.swap(sp4);std::cout << "After swap, sp1 address: " << sp1.get() << ", sp4 address: " << sp4.get() << std::endl;// 当main()函数结束时, sp1, sp2, sp3, sp4将自动被析构,并且它们所拥有的对象也将被删除// 因为sp1, sp2, sp3指向同一个对象,所以只有当最后一个shared_ptr被销毁后对象才会被删除// sp4指向一个不同的对象,将独立于sp1, sp2, sp3进行析构return 0;
}

运行结果:
运行结果

引用计数增加:

  1. 拷贝 shared_ptr。
  2. 作为参数传递给函数。
  3. 作为函数返回值。

引用计数递减:

  1. 给 shared_ptr 赋予一个新值。
  2. shared_ptr被销毁(例如:局部 shared_ptr 离开作用域)。

引用计数为0, shared_ptr 释放所管理的对象。

析构函数:对象销毁时,释放对象所分配的资源。

使用动态生存期的资源的类:

  1. 程序不知道自己需要使用多少对象(容器类)。
  2. 程序不知道所需对象的准确类型。
  3. 程序需要在多个对象间共享数据。

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

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

相关文章

矩阵的归一化技术

矩阵的归一化&#xff08;Normalization&#xff09;是将矩阵中的元素缩放到一个特定的范围或者标准&#xff0c;使得在进行比较、评估或计算时能够保持数值稳定性和可比性。这个过程在数据预处理、机器学习、图像处理等领域中非常重要。归一化有助于改善算法的收敛速度和精度&…

Lumos学习python第七课:字符串

一、老规矩&#xff0c;题目呢&#xff1f; 1、题目-----来源力扣 罗马数字包含以下七种字符: I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C …

LeetCode_1.两数之和

一、题目描述 二、方法 1.方法1&#xff08;暴力枚举法&#xff09; 利用两个for循环&#xff0c;对数组进行逐一的遍历&#xff0c;直到找到两个数的和为目标值时返回这两个数的下标。以下为c实现的完整代码。 # include<iostream> using namespace std; #include<…

消息队列经典应用场景

笔者心中,消息队列,缓存,分库分表是高并发解决方案三剑客。 在职业生涯中,笔者曾经使用过 ActiveMQ 、RabbitMQ 、Kafka 、RocketMQ 这些知名的消息队列 。 这篇文章,笔者结合自己的真实经历,和大家分享消息队列的七种经典应用场景。 1 异步&解耦 笔者曾经负责某电…

戴尔灵越3000来说2.5G的双核显存能干啥?

吃鸡已经成为大家耳熟能详的网络游戏。 很多人认为&#xff0c;想要享受吃鸡的乐趣&#xff0c;就必须组装一台高端电脑。 虽然配置越高越好&#xff0c;但现实是很多配置都是以性能为标准的。 有余了&#xff0c;没必要刻意追求高配置、高特效。 说实话&#xff0c;吃鸡不一定…

Linux之文件系统

我们之前谈到的文件描述符fd,是与被加载到内存中的文件相关的&#xff0c;那么还有什么文件呢&#xff1f;磁盘文件 内存文件 ------ 断电失效 磁盘文件 ------ 不受断电的影响 磁盘存储器存、取信息的最基本单位是扇区。 —个扇区能存储512Bytes的数据,OS与磁盘交互的单位…

CSS及javascript

一、CSS简介 css是一门语言&#xff0c;用于控制网页的表现。 cascading style sheet:层叠样式表 二、css的导入方式 css代码与html代码的结合方式 &#xff08;1&#xff09;css导入html有三种方式&#xff1a; 1.内联样式&#xff1a;<div style"color:red&quo…

视频素材免费哪个好?7个视频素材下载网站推荐

小伙帮们准备做视频的时候才发现&#xff0c;哎呀&#xff0c;高清视频素材哪里找啊&#xff1f;不用急&#xff0c;这次我们依旧从中国的宝藏网站开始&#xff0c;然后穿越全球&#xff0c;发现更多精彩的无水印视频素材网站 1&#xff0c;蛙学府&#xff08;中国&#xff09…

URL编码:原理、应用与安全性

title: URL编码&#xff1a;原理、应用与安全性 date: 2024/3/29 18:32:42 updated: 2024/3/29 18:32:42 tags: URL编码百分号编码特殊字符处理网络安全应用场景标准演变未来发展 在网络世界中&#xff0c;URL&#xff08;统一资源定位符&#xff09;是我们访问网页、发送请求…

【ENSP】交换机和路由器之间实现静态路由

1.概念 三层交换机只能在Vlanif逻辑口配置iP地址 路由器的每一个端口都是另外一个网段 2.实现方法 交换机允许对应vlan通行&#xff0c;配置vlanif的ip地址&#xff0c;做静态路由 路由器&#xff0c;进接口配置对应的ip&#xff0c;路由器和交换机相连的口&#xff0c;进入他的…

Unity AI Navigation自动寻路

目录 前言一、Unity中AI Navigation是什么&#xff1f;二、使用步骤1.安装AI Navigation2.创建模型和材质3.编写向目标移动的脚本4.NavMeshLink桥接组件5.NavMeshObstacle组件6.NavMeshModifler组件 三、效果总结 前言 Unity是一款强大的游戏开发引擎&#xff0c;而人工智能&a…

基于 FFmpeg 和 SDL 的音视频同步播放器

基于 FFmpeg 和 SDL 的音视频同步播放器 基于 FFmpeg 和 SDL 的音视频同步播放器前置知识音视频同步简介复习DTS、PTS和时间基 程序框架主线程解复用线程音频解码播放线程视频解码播放线程 音视频同步逻辑源程序结果工程文件下载参考链接 基于 FFmpeg 和 SDL 的音视频同步播放器…