内存管理--3.用幻灯片讲解C++手动内存管理

用幻灯片讲解C++手动内存管理

1.栈内存的基本元素

在这里插入图片描述

2.栈内存的聚合对象

在这里插入图片描述

3.手动分配内存和释放内存

注意:手动分配内存,指的是在堆内存中。
除非实现自己的数据结构,否则永远不要手动分配内存!
即使这样,您也应该通过std::allocator_traits使用分配器。(注:allocator_traits是STL库的对自定义内存分配器的统一接口)
在这里插入图片描述

4.在堆上手动分配内存

p被当做拥有一个原始指针。这幅幻灯片有个bug,不知各位看出来没有?
在这里插入图片描述

5.手动分配数组内存和释放数组内存

注意:释放数组内存delete后一定要带[ ],否则程序将产生不可预知的后果,大概率是报内存错误后程序挂掉,因为你只释放了数组的一个元素的内存,其它内存没有释放,造成了内存泄漏。
作者再次强调了:
除非实现自己的数据结构,否则永远不要手动分配内存!
即使这样,您也应该通过std::allocator_traits使用分配器。
在这里插入图片描述

6.手动分配数组内存

在这里插入图片描述

7.不要使用拥有的原始指针

  • 指针指向已经删除的内存怎么办?
  • 如果指针指向其他进程保留的内存怎么办?
  • 我们必须手动跟踪分配(new)和解除分配(delete)
  • 非常容易出错,可能导致难以捕捉的bug

下图就是一个经典的错误,释放内存后,用户忘记了已经释放,然后又向p指向的内存写入值,产生内存错误,程序挂掉!
在这里插入图片描述

8.黑暗时代和现代C++时代

黑暗时代(C++11之前)

  • 拥有原始指针
  • 经常在不同的代码点显式的new和显示的delete
  • 非直观界面
  • 内存易泄漏

现代C++时代

智能指针
  • 自动删除对象
  • 自我文档化接口/所有权(指由智能指针来管理内存,不需要用户关系具体细节)
  • 没有内存泄漏
    在这里插入图片描述

9.地址检测器(ASAN)

  • 支持的编译器:g++、clang++
  • 检测内存错误
    • 内存泄漏
    • 访问已经释放的内存
    • 访问不正确的堆栈区域
  • 使用附加说明检测您的代码
    • 运行时间增加约70%
    • 内存使用量增加了大约3倍

注:ASAN是谷歌开发的一个动态内存检测器,可以检测出各种内存相关的错误。
在这里插入图片描述

10.示例:检测空指针

在这里插入图片描述

11.使用ASAN

在这里插入图片描述

12.Valgrind工具

(Valgrind 是一个强大的内存调试和性能分析工具集,广泛应用于 C/C++ 等编程语言的软件开发和分析中。)

检测常见运行时错误。

  • 读/写释放的内存或不正确的堆栈区域。
  • 使用未初始化的值。
  • 不正确的内存释放,如双重释放。
  • 滥用内存分配函数。
  • 内存泄漏-无意内存泄漏通常与程序逻辑缺陷有关,这些缺陷导致内存指针在重新分配之前丢失。

Windows:

Dr.Memory (www.drmemory.org) (Windows平台上的C/C++内存错误检查器)
Windows 10 64位:在WSL中的Valgrind
在这里插入图片描述

13.Valgrind使用

在这里插入图片描述
在这里插入图片描述

14.标准库中的异常

operator new 会抛出以下异常:

  • std::bad_alloc 如果内存没有被成功分配
  • std::bad_new_array_size 如果数组长度小于0或者太大
    在这里插入图片描述

15.异常安全性的含义

内存泄漏的潜在来源
如下图的示例,如果文件不存在抛出异常后则就会造成buf指向的内存没有被释放,内存泄漏!
在这里插入图片描述

16.智能指针工程及其异常安全性

  • C++标准要求:
    • 所有函数参数必须在进入函数前求值。
    • 未指定函数参数求值顺序。
  • 6种参数求值顺序的两种。
    在这里插入图片描述

下图可能会造成内存泄漏

可能的求值顺序:

  1. new Widget{}
  2. Gadget{}
  3. unique_ptr{}

如果Gadget构造函数抛出异常

  • Widget对象已经构建(在堆上)
  • unique_ptr尚未获取Widget对象的所有权
  • Widget对象泄漏
    在这里插入图片描述
    下图代码就不可能有内存泄露:
  • 调用make_unique()在Gadjet构造函数调用之前或之后完全计算。
  • 如果Gadget构造函数抛出异常:
    • 则Widget已经被unique_ptr所拥有,
    • 无论如何,Widget都会被正确地销毁。
  • 使用 make_unique和make_shared来创建智能指针!
    在这里插入图片描述
    希望文章对您有所帮助,整理不易,请随手点个赞!原文链接:hackingcpp.com

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

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

相关文章

如何在本地和远程删除 Git 分支

欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英杰,211科班出身,就职于医疗科技公司,热衷分享知识,目前是武汉城市开发者社区主理人 擅长.net、C、python开发, 如果遇…

计算机组成原理之指令格式

1、指令的定义 零地址指令: 1、不需要操作数,如空操作、停机、关中断等指令。 2、堆栈计算机,两个操作数隐藏在栈顶和此栈顶,取两个操作数,并运算的结果后重新压回栈顶。 一地址指令: 二、三地址指令 四…

selenium-java自动化教程

文章目录 Selenium支持语言WebDriver 开始使用chromedriver模拟用户浏览访问模拟点击事件关闭弹窗,选中元素并点击 获取页面文本结语 Selenium Selenium是一个自动化测试工具,可以模拟用户操作web端浏览器的行为,包括点击、输入、选择等。也可…

高考后志愿填报信息采集系统制作指南

在高考的硝烟散去之后,每位学生都面临着一个重要的任务——志愿填报。老师们如何高效、准确地收集和整理这些信息,成为了一个棘手的问题。难道我们只能依赖传统的手工登记方式,忍受其繁琐和易错吗? 易查分是一个简单易用的在线工具…

数据结构--递归和数组

个人介绍 hello hello~ ,这里是 code袁~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 🦁作者简介:一名喜欢分享和记录学习的…

ESP32:FreeRTOS节拍配置(vTaskDelay延时10ms改为1ms)

文章目录 背景方法手动修改sdkconfig通过idf.py menuconfig 背景 在FreeRTOS的默认配置中,任务调度的频率默认是100HZ,因此默认vTaskDelay默认延时是10ms。 FreeRTOS 的系统时钟节拍可以在配置文件 FreeRTOSConfig.h 里面设置:#define confi…

论文阅读KAN: Kolmogorov–Arnold Networks

学习了最近大热的KAN网络 论文地址:https://arxiv.org/pdf/2404.19756 按我个人读论文的习惯总结了如下几点: 1,背景: 1)灵感来源:于Kolmogorov-Arnold表示定理,也就是多变量连续函数可以表…

技术与业务的完美融合:大数据BI如何真正提升业务价值

数据分析有一点经典案例 沃尔玛的啤酒和尿布案例 开始做BI的时候,大家肯定都看过书,那么一定也看过一个经典的案例,就是沃尔玛的啤酒和尿布的案例。这个案例确实很经典,但其实是一个失败的案例。为什么这么说呢?很明显…

html接口响应断言

接口响应值除类json格式,还有html格式 断言步骤 第一步:替换空格replace 原本返回的格式和网页内容一致,每行前面有很多空格,需要去除这些空格 第二步:分割split 因为行与行之前有回车符,所以把回车符替…

JAVA-LeetCode 热题 100 第56.合并区间

思路&#xff1a; class Solution {public int[][] merge(int[][] intervals) {if(intervals.length < 1) return intervals;List<int[]> res new ArrayList<>();Arrays.sort(intervals, (o1,o2) -> o1[0] - o2[0]);for(int[] interval : intervals){if(res…

cisco packet tracer 8.2.2 (思科模拟器) ospf路由协议

1 实验拓扑图 2 配置路由器和交换机 #sw1 en config t hostname sw1 ip routing int vlan 2 ip address 192.168.2.1 255.255.255.0 exit int vlan 3 ip address 192.168.3.1 255.255.255.0 exit int gigabitEthernet 1/0/1 switchport access vlan 2 exit int gigabitEthe…

在AMD GPU上加速大型语言模型的Flash Attention

Accelerating Large Language Models with Flash Attention on AMD GPUs — ROCm Blogs 引言 在这篇博客文章中&#xff0c;我们将指导您如何在AMD GPU上安装Flash Attention&#xff0c;并提供与在PyTorch中标准SDPA比较其性能的基准测试。我们还将测量Hugging Face中多个大型…

Facebook革新:数字社交的下一个阶段

在数字化时代&#xff0c;社交网络已经成为人们生活中不可或缺的一部分。作为全球最大的社交网络平台之一&#xff0c;Facebook一直在不断创新&#xff0c;引领着数字社交的发展。然而&#xff0c;随着科技的不断进步和社交需求的变化&#xff0c;Facebook正在走向一个新的阶段…

Linux下软件安装

提示&#xff1a;制作不易&#xff0c;可以点个关注和收藏哦。 前言 介绍 Ubuntu 下软件安装的几种方式&#xff0c;及 apt&#xff0c;dpkg 工具的使用。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考. 一、先体验一下 比如我们想安装一个软件&…

添加Microsoft.VisualStudio.TestTools.UnitTesting命名空间

创建“单元测试项目”&#xff0c;则自动添加 Microsoft.VisualStudio.TestTools.UnitTesting 命名空间

C语言:双链表

一、什么是双链表&#xff1f; 双链表&#xff0c;顾名思义&#xff0c;是一种每个节点都包含两个链接的链表&#xff1a;一个指向下一个节点&#xff0c;另一个指向前一个节点。这种结构使得双链表在遍历、插入和删除操作上都表现出色。与单链表相比&#xff0c;双链表不仅可以…

卡尔曼滤波器例子

卡尔曼滤波器 卡尔曼滤波器(Kalman Filter)是一种用于线性系统状态估计的递归算法,可以有效地融合传感器数据和系统模型来估计系统的状态。它在机器人学中广泛应用,尤其是位置和速度等状态的估计。通过卡尔曼滤波器,可以有效地估计机器人在二维平面内的真实位置,并减小测…

真空衰变,真正的宇宙级灾难,它到底有多可怕?

真空衰变&#xff0c;真正的宇宙级灾难&#xff0c;它到底有多可怕&#xff1f; 真空衰变 真空衰变&#xff08;Vacuum decay&#xff09;是物理学家根据量子场论推测出的一种宇宙中可能会发生的现象&#xff0c;这种现象被称为真正的宇宙级灾难&#xff0c;它到底有多可怕呢…

Java:112-SpringMVC的底层原理(下篇)

这里继续续写上一章博客&#xff08;111章博客&#xff09;&#xff1a; Spring MVC 源码深度剖析&#xff1a; 既然我们自行写出了一个&#xff0c;那么我们可以选择看看mvc源码&#xff1a; 前端控制器 DispatcherServlet 继承结构&#xff1a; 前面我们知道mvc是操作同…

动态规划学习(分组背包)

分组背包的定义 分组背包是相比于01背包来讲&#xff0c;其就是多了一个组&#xff0c;给你n个组&#xff0c;每个组里有各自的物品&#xff0c;每个组里的物品只能选择一个&#xff0c;问你&#xff0c;选出来的最大价值是多少 这里我们的遍历顺序的三层循环&#xff0c;最外…