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

news2024/12/24 2:03:11

内存分配的每一层面

在这里插入图片描述
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的例子
在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android adb logcat日志过滤输出

Android adb logcat日志过滤输出 adb logcat 输出所有Android设备上的日志。 adb logcat *:Error 过滤输出日志级别只为Error的日志。 过滤某些标签或tag,依次执行: adb shell logcat grep | "你的标签或tag" Android Studio level过滤查看各个等级的日志…

数据列表组件-报表

当数据在后端接口查询到&#xff0c;需要在页面展示出来&#xff0c;如果项目有很多report &#xff0c;可以把列表做一个组件 效果如下&#xff1a; js代码&#xff1a; <!DOCTYPE html> <html> <head><meta charset"utf-8" /><title&g…

大白菜U盘启动工具

大白菜如何u盘启动进winpe装系统大白菜是一款非常实用的U盘启动盘制作工具&#xff0c;可以帮助用户快速地将U盘制作成启动盘&#xff0c;从而方便地进行系统安装、维护和修复等操作。官方网站&#xff1a; 大白菜u盘启动盘制作工具_大白菜u盘装系统_大白菜pe_大白菜官网-首页…

顶级10大AI测试工具

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Elasticsearch集群部署(下)

目录 上篇&#xff1a;Elasticsearch集群部署&#xff08;上&#xff09;-CSDN博客 七. Filebeat 部署 八. 部署Kafka 九. 集群测试 链接&#xff1a;https://pan.baidu.com/s/1AFXSmDdY5xBb7g35ipKoaw?pwdfa9m 提取码&#xff1a;fa9m 七. Filebeat 部署 为什么用 F…

# Kafka_深入探秘者(9):kafka 集群管理

Kafka_深入探秘者&#xff08;9&#xff09;&#xff1a;kafka 集群管理 一、kafka 集群概述 1、kafka 集群概述&#xff1a; 集群是一种计算机系统&#xff0c;它通过一组松散集成的计算机软件和/或硬件连接起来高度紧密地协作完成计算工作。在某种意义上&#xff0c;他们可…

腾讯云函数部署环境[使用函数URL]

使用函数URL 之前使用的是网关API,最近腾讯云的网关API说要关闭了,所以没有办法这里改成函数URL,使用后发现只要不是在浏览器直接访问的情况,函数URL都可以满足! 这里结合腾讯云函数node.js返回自动带反斜杠这篇文章来做说明,比如这里的URL如下: 结合文章腾讯云函数node.js返…

股票分析-20240628

今日关注&#xff1a; 20240626 六日涨幅最大: ------1--------300386--------- 飞天诚信 五日涨幅最大: ------1--------300386--------- 飞天诚信 四日涨幅最大: ------1--------300386--------- 飞天诚信 三日涨幅最大: ------1--------300386--------- 飞天诚信 二日涨幅最…

【软件测试】之自动化测试

&#x1f3c0;&#x1f3c0;&#x1f3c0;来都来了&#xff0c;不妨点个关注&#xff01; &#x1f3a7;&#x1f3a7;&#x1f3a7;博客主页&#xff1a;欢迎各位大佬! 文章目录 什么是自动化测试Selenium介绍什么是SeleniumSelenium的特点工作原理 SeleniumJava环境搭建下载…

springboot城市菜园共享系统-计算机毕业设计源码00524

目 录 摘要 1 绪论 1.1 研究背景与意义 1.2 国内外研究现状和发展趋势 1.3论文结构与章节安排 2 城市菜园共享系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.…

【Linux小命令】一文讲清ldd命令及使用场景

一文讲清ldd命令及使用场景 前言下面进入正题&#xff1a;ldd命令 前言 博主今天ubuntu编译go项目出来的一个可执行文件&#xff0c;放centos运行发现居然依赖于XXlib库。然后我一下就想到两个系统库版本不一致&#xff0c;重编。换系统&#xff0c;导项目&#xff0c;配环境……

YUV 颜色编码详解

YUV 简介 YUV是被欧洲电视系统所采用的一种颜色编码方法&#xff08;属于PAL&#xff09;&#xff0c;是PAL和SECAM模拟彩色电视制式采用的颜色空间。在现代彩色电视系统中&#xff0c;通常采用三管彩色摄影机或彩色CCD摄影机进行取像&#xff0c;然后把取得的彩色图像信号经分…

Swift Core Data 分阶段迁移

文章目录 前言什么是分阶段迁移&#xff1f;提供一些背景信息创建迁移管理器设置使用 Core Data 栈。总结 前言 在这之前&#xff0c;我发布了一篇文章&#xff0c;在其中解释了如何使用映射模型和自定义迁移策略执行复杂的 Core Data 迁移。虽然这种方法性能良好且运行良好&a…

鸿蒙小案例-自定义键盘

一个自定义键盘 效果 完成简单的26键中英文输入 使用&#xff1a; Entry Component struct IndexInput {State text: string inputController: TextInputController new TextInputController()//自定义键盘关闭事件hideClick(){this.inputController.stopEditing()}//自定义…

自动化设备上位机设计 一

目录 一 设计原型 二 后台代码 一 设计原型 二 后台代码 namespace 自动化上位机设计 {public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){}} }namespace 自动化上位机设计 {partial class Fo…

GPU相关的一些截图(备查,待整理)

GPU相关的一些截图 这里记录一些与GPU相关的截图,方便查阅

线段树求区间最值问题

引言 今天主要还是练了两道题&#xff0c;是有关线段树如何去求一个区间内的最值问题的&#xff0c;我们可以用线段树来解决。 对应一个无法改变顺序的数组&#xff0c;我们想要去求一个区间内的最值&#xff0c;假设有n个结点&#xff0c;m次询问&#xff0c;暴力的解决办法…

【高校科研前沿】南京地理与湖泊研究所博士后夏凡为第一作者在环境科学与水资源领域Top期刊发文:钙对云南洱海溶解有机质与浮游细菌相互作用的调控作用

文章简介 论文名称&#xff1a;Calcium regulates the interactions between dissolved organic matter and planktonic bacteria in Erhai Lake, Yunnan Province, China 第一作者及单位&#xff1a;夏凡&#xff08;博士后|中国科学院南京地理与湖泊研究所&#xff09; 通讯…

关于虚拟机CentOS 7使用ssh无法连接(详细)

虚拟机CentOS 7使用ssh无法连接 猜测&#xff1a;可能是虚拟机软件的网关和和centos7的网关不同导致的问题。 首先打开CentOS7的终端, 输入ifconfig&#xff0c;查看一下系统的ip 打开虚拟机的虚拟网络编辑器, 查看一下网关, 发现确实不一样. 这里有两种方式, 要么修改虚…

fluwx插件实现微信支付

Flutter开发使用fluwx插件实现微信支付&#xff0c;代码量不多&#xff0c;复杂的是安卓和iOS的各种配置。 在 pubspec.yaml 文件中添加fluwx依赖 fluwx: ^4.5.5 使用方法 通过fluwx注册微信Api await Fluwx().registerApi(appId: wxea7a1c53d9e5849d, universalLink: htt…