C++内存管理(候捷)第一讲 笔记

内存分配的每一层面

在这里插入图片描述
applications可以调用STL,里面会有allocator进行内存分配;也可以使用C++ 基本工具primitives,比如new, new[], new(), ::operator new();还可以使用更底层的malloc和free分配和释放内存。最底层的是系统调用,比如HeapAlloc,VirtualAlloc
在这里插入图片描述
在C中,malloc 和 free 是标准库函数,不涉及构造函数和析构函数,只是简单的内存分配和释放

int *ptr = (int *)malloc(sizeof(int));
free(ptr);

在C++中,new 和 delete 不仅仅是内存分配和释放的操作符,还会处理对象的构造和析构

四个层面的基本用法

在这里插入图片描述
malloc和 ::operator new()是完全一样的效果
allocator()是创建一个临时对象来调用非static函数
在这里插入图片描述
__GNUC__版本4.9的分配器

基本构件之一new delete expression上

在这里插入图片描述
由于有分配内存,因此要try catch考虑内存分配失败时如何处理
new的过程:1.分配内存 2.指针转型 3.调用构造函数

在指定内存上创建对象使用placement new:new (pointer) Type(initializer);

void* memory = operator new(sizeof(MyClass)); // 分配内存
MyClass* obj = new (memory) MyClass(/* constructor arguments */); // 在指定内存位置创建对象
void* memory = operator new[](sizeof(MyClass) * 5); // 分配数组内存
MyClass* objArray = new (memory) MyClass[5]; // 在数组内存中创建对象

_callnewh 不是 C++ 标准中的函数,而是可能是用户定义的一个函数。通常情况下,这类函数的名字以 _new_handler 结尾,用于处理内存分配失败的情况。
在 C++ 中,当 new 表达式无法分配所需的内存时,会调用用户指定的 new_handler 函数。new_handler 是一个函数指针,指向一个用户定义的函数,其原型通常为

typedef void (*new_handler)();

这个函数可以尝试释放内存、扩大内存池,或者执行其他操作来尝试解决内存不足的问题。如果 new_handler 能够成功处理内存不足的情况,返回;如果不能处理,可以选择抛出异常或者终止程序

基本构件之一new delete expression中

在这里插入图片描述
使用定位 new 运算符后,必须手动调用对象的析构函数来释放资源,否则可能导致内存泄漏

obj->~MyClass(); // 手动调用析构函数
operator delete(memory); // 手动释放内存

delete的动作:先调用析构函数,然后释放内存。
operator delete里调用free

基本构件之一new delete expression下

在这里插入图片描述
ctor和dtor直接调用的测试

Array new

在这里插入图片描述
cookie记录的是下面一块的长度。malloc分配的时候会额外带上一块cookie的信息,供给free释放
在这里插入图片描述
测试
在这里插入图片描述
vc6下malloc new int[10]内存布局:灰色表示具体数据,橙色是debug模式下添加的内存。上面和最下面的两个0x61(61H)是cookie,记录整体内存分配的大小。61H实际上是60H,表示内存分配的大小,后面1H意思是占用最后一位,表示内存分配出去。浅蓝色的pad表示补齐,填补到16的倍数
在这里插入图片描述
在这里插入图片描述

placement new

在这里插入图片描述
placement new允许我们将对象建构在已经分配好的内存中

Complex* pc = new(buf)Complex(1, 2);这句话会被编译器转换为,分别调用operator new(需要第二个参数,表示位置,这个函数只是传回这个位置,不再分配内存),指针转型,调用构造函数

重载

在这里插入图片描述
new是表达式,不可改变不可重载。会调用 operator new,全局(可重载但少见)或者成员函数(可重载)
在这里插入图片描述
容器里把构造函数和析构函数包装在 construct()和destroy(),内存分配动作allocate()和deallocate()会走入分配器allocator中处理

容器分配内存的一般途径:容器使用分配器,在这里插入图片描述
分配器调用 ::operator new 和 ::operator delete,底层可能调用 malloc 和 free:
在这里插入图片描述
重载全局的::operator new 和::operator delete
在这里插入图片描述
在一个类中重载operator new和operator delete。编译器会自动调用
通常会加static,因为调用的地方通常在创建对象的过程中,无法通过对象来调用一般函数
在这里插入图片描述

重载示例

在这里插入图片描述
在这里插入图片描述
重载示例
有虚函数只是把大小放大了,一个12,一个16
在GNU C++4.9版本中构造是从上到下,析构是从下到上
在这里插入图片描述
使用全局new,delete示例
在这里插入图片描述
placement new的重载第一参数必须是size_t类型,接受类的大小,会传入Foo的大小。其余的参数就是括号里的参数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
平常使用的string,就是个typedef ,define basic_string。重载了operator new。每次创建时也额外分配字符串大小的内存

Per class allocator

在这里插入图片描述
内存池:用malloc分配一大块(内存池),然后分成小块,减少malloc的调用次数。另外减少cookie的用量。
在Screen类中引入一个指针next,它的大小是4B,用于串联链表
delete操作,把指针p回收到单向链表中,放到链表的头指针位置
在这里插入图片描述
左边间隔8表示每个Screen对象内存分配的大小为8B,说明每个Screen分配的时候没有cookie。
右边间隔16,表示每个Screen对象内存分配的大小为16B,这是因为对象分配的时候上下加了cookie,最上面和最下面的cookie大小共为8B

Per class allocator 2

在这里插入图片描述
struct AirplaneRep,由于对齐,5B会变成8B
union 是一种特殊的数据结构,可以看作同一个东西,用不同的名称/不同的角度去看待。
上述例子用指针去看待union时,只看8个字节的前4个字节

通过union借用内存块的前4个字节当作指针
在这里插入图片描述
delete没有free,只是把区块回收到链表,并未把内存还给操作系统,链表可能会越来越长,超过512块

Static allocator

从软件工程的角度看,上面的operator new和operator delete对于不同 类都要重载,明显不是一个好的解法,因此将allocator抽象成一个类。

具体的类进行内存分配的时候,只需要调用allocator即可
在这里插入图片描述
在这里插入图片描述
嵌入式指针embedded pointer:借用A对象所占用的内存空间中的前4个字节,这4个字节用来 链住这些空闲的内存块;但是,一旦某一块被分配出去,那么这个块的 前4个字节 就不再需要。因此类A对象的sizeof必须不小于4字节

上述例子定义一个类型obj,不放在外部,污染全局变量。struct里放了一个指针,它的大小为4个字节。这个指针的值,存着下一个内存的地址。由于这里只需要指针,所以union可以不使用。
在这里插入图片描述
由于上面的CHUNK设置为5,每5个对象的内存空间是连续的(间隔都是一个对象的大小),而每个大块之间是不连续的。

Macro for static allocator

在这里插入图片描述
把allocator的部分拿出来用宏来定义
宏是预处理指令,用于在编译过程中执行文本替换。宏通常通过 #define 关键字定义,并在代码中通过宏名称来调用。它们是一种简单的文本替换机制,可以用于创建常量、函数替代、条件编译等。
在宏定义的末尾使用反斜杠是为了告诉编译器该宏定义将在下一行继续。如果在宏定义的最后一行没有使用反斜杠,那么编译器会认为宏定义结束了

版本1:指针,版本2:embedded pointer,版本3:抽取内存的动作到单一class Allocator 版本4:alloctator通过宏抽取出来
在这里插入图片描述
标准库中的allocator
其中一种分配器有16条自由链表,来应对不同大小的块分配,不同的大小的类对象,分配到不同的链表中

New Handler

在这里插入图片描述
new handler 是一个函数指针,当 new 操作符无法分配所需的内存时,会调用与之关联的 new handler
new handler 是全局的,一旦设置,会在程序的生命周期内一直有效,直到被其他 set_new_handler 覆盖
在这里插入图片描述
new handler的例子
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

明星代言6个提升企业形象的杀手锏-华媒舍

在当今竞争激烈的商业世界中,企业形象的塑造对于品牌的发展至关重要。而明星代言作为一种常见的营销手段,被广泛使用来提升企业形象和产品销售。本文将介绍明星代言的六个杀手锏,帮助您了解如何通过明星代言来提升企业形象。 1. 拥有广泛的影…

十二、【源码】Spring整合AOP

源码地址:https://github.com/spring-projects/spring-framework 仓库地址:https://gitcode.net/qq_42665745/spring/-/tree/12-spring-aop Spring整合AOP 核心类: DefaultAdvisorAutoProxyCreator:用于在Spring框架中自动为符…

若依多数据源原理分析

首先,想明白不同的接口想要使用不同的数据源。 那么自然想到了AOP,自定义注解。 通过自定义注解标注当前方法到底使用的是哪个数据源。 上面是前置条件。 看下若依是怎么处理的: 1.定义自定义注解,以及对应的多数据源的枚举类…

天润融通分析AI技术助力客户服务,实现满意度三倍增长

如今,客户体验越来越成为影响客户决策的核心要素。 对于企业来讲,客户在不同触点的每一次互动体验,都成为塑造品牌声誉的“Aha时刻”。但同时,随着社会的发展的加速,客户的需求也在日新月异,给企业带来挑战…

Codeforces Round 955 (Div. 2, with prizes from NEAR!)(A~C题解)

这场比赛怎么说呢,一开始打的还算好,能进前1000,但是后面就被卡住了,这个确实没办法水平还是不够,学过的还是没想起来,后面继续练 A. Soccer 题解:水题一个,想要在过程中出现平局的…

web零碎知识

&nbsp 在html文件中 连续的空格会被认为是一个空格 所以我们需要使用&nbsp来代表空格 &#x3000 把这个当成tab键来使用 我们可以引入js文件,就可以减少html文件的长度。 首先创建一个js文件夹,然后在js文件夹中创建一个,后缀…

【第17章】MyBatis-Plus自动维护DDL

文章目录 前言一、功能概述二、注意事项三、代码示例四、实战1. 准备2. ddl配置类3. 程序启动4. 效果(数据库) 总结 前言 在MyBatis-Plus的3.5.3版本中,引入了一项强大的功能:数据库DDL(数据定义语言)表结构的自动维护。这一功能…

【电路笔记】-B类放大器

B类放大器 文章目录 B类放大器1、概述2、B类放大器介绍3、推挽式配置4、限制交叉失真5、B类放大器效率6、总结1、概述 我们在之前的文章中已经知道,A 类放大器的特点是导通角为 360,理论最大效率为 50%。 在本文中,我们将详细介绍另一类放大器,称为B类放大器,它是为解决A…

康姿百德磁性床垫好不好,效果怎么样靠谱吗

康姿百德典雅款床垫,打造舒适睡眠新体验 康姿百德床垫是打造舒适睡眠新体验的首选,其设计能够保护脊椎健康,舒展脊椎,让您享受一夜好眠。康姿百德床垫的面料选择也非常重要,其细腻亲肤的针织面料给您带来柔软舒适的触…

A*——AcWing 179. 八数码

A* 定义 A* 算法是一种在图形或地图中寻找最短路径的启发式搜索算法。它通过综合考虑起始节点到当前节点的实际代价和当前节点到目标节点的预估代价,来决定下一步的搜索方向。 运用情况 路径规划:如在地图导航中为车辆、行人规划最优路线。游戏开发&…

旅游系统(附管理端+前台)PHP源码

一. 前言 今天小编给大家带来了一款可学习,可商用的,旅游系统 源码,支持二开,无加密。支持景点管理,登录,景点预定,意见反馈,统计等功能。详细界面和功能见下面视频演示。 二. 视频…

深入挖掘海外快手kwai ads推广巴西slots手游广告独家优势

深入挖掘海外快手kwai ads推广巴西slots手游广告独家优势 在数字化时代,广告投放已成为各行各业不可或缺的一部分,特别是在游戏行业,如何有效地推广游戏产品,吸引玩家的眼球,成为了每一个游戏开发商和广告主所关注的焦…

DllImport进阶:参数配置与高级主题探究

深入讨论DllImport属性的作用和配置方法 在基础篇中,我们已经简单介绍了DllImport的一些属性。现在我们将深入探讨这些属性的实际应用。 1. EntryPoint EntryPoint属性用于指定要调用的非托管函数的名称。如果托管代码中的函数名与非托管代码中的函数名不同&#…

TreeSize Free - 硬盘空间管理工具

TreeSize FreeTreeSize Free 是一款免费的强大灵活的硬盘空间管理工具。可以帮你找出硬盘上最大的目录以及它占用的空间。支持空间大小显示、分配空间和占用空间、文件数、3D工具条和分配图、最近使用数据、文件作者、NTFS压缩率等信息,并支持搜索文件。该软件类似浏…

掌握亚马逊自养号:测评策略的核心要点与实战经验

在当今电商领域的激烈角逐中,亚马逊测评对于卖家而言,已从单纯的销量助推器与好评累积工具,进化为品牌塑造与市场洞察的关键环节。然而,许多卖家仍局限于传统认知,未能充分挖掘自养号测评的多元化价值与深远影响。本文…

Modbus协议转Profinet协议网关模块连智能仪表与PLC通讯

一、现场需求:PLC作为控制器,仪表设备做为执行设备,执行设备能够实时响应PLC传来的指令,并且向PLC回馈数据,从而达到PLC对仪表设备进行控制和监测,实现对生产过程的精准控制。 二、解决方案:通过…

2024年7月5日 十二生肖 今日运势

小运播报:2024年7月5日,星期五,农历五月三十 (甲辰年庚午月庚午日),法定工作日。 红榜生肖:狗、羊、虎 需要注意:鸡、牛、鼠 喜神方位:西北方 财神方位:正…

java考试题20道

选择题 编译Java源代码文件的命令是javac javac命令是将Java源代码文件进行编译得到字节码文件(.class文件) java命令是在JVM上运行得到的字节码文件 下面是一个示例: javac test.java -------> test.class java test ------> 运行test.class文件下列那…

QT_GUI

1、QT安装 一个跨平台的应用程序和用户界面框架,用于开发图形用户界面(GUI)应用程序以及命令行工具。QT有商业版额免费开源版,一般使用免费开源版即可,下面安装的是QT5,因为出来较早,使用较多&…

以品质为初心,以创新为驱动,光明乳业闪耀第十五届中国奶业大会

2024年7月3日,以“数智赋能引领产业发展增长点,科技创新驱动奶业新质生产力”为主题的中国奶业协会第十五届奶业大会奶业20强(D20)论坛暨2024中国奶业展览会隆重召开,光明乳业党委书记、董事长黄黎明受邀出席会议&…