c++内存管理_复习

  • new与placement new
    • new:

      • 先调用operator new(大小),而operator new()会调用malloc尝试分配内存,失败则调用_callnewh()来释放内存,直至分配成功
        • 可以设置分配失败的处理函数:将写好的处理函数作为参数传入set_new_handler即可
      • 然后将得到的指针转型
      • 最后通过指针调用构造函数
    • placement new
      placementnew

      • 先调用operator new(大小, address),该带2个参数的函数直接返回buf,不做任何改动,即不分配内存。
      • 然后将得到的指针转型
      • 最后通过指针调用构造函数

总结:new会分配内存后调用构造函数,而placement new相当于只是调用构造函数。因此我们可以像下面这样模拟new的行为:
模拟new和delete

  • 容器的内存分配方式
    当元素放入容器时,容器也需要为其分配一块空间,但其不是用的new和delete,而是将其包装在construct()和destroy()函数中

  • 设计一个内存池

    • 重载局部的operator new()
      • 方法1:单独多使用一些指针来将空闲块连成链表
        下面在节点中使用next指针来将小块链接起来

        void* A::operator new(size_t size)
        {cout << "局部new" << endl;A* p;if (!A::freeStore){//申请一大块空间//A::freeStore = (A*)malloc(size * Chunk);A::freeStore = reinterpret_cast<A*>(new char[Chunk*size]);p = A::freeStore;//初始化p指针也指向头节点//串成链表for (int i = 0; i < Chunk; i++){p->next = p + 1;//地址增大4,就是一个A的大小p = p->next;}p->next = NULL;}//把链表头部的空闲块拿出来用p = A::freeStore;A::freeStore = A::freeStore->next;return p;
        }
        
      • 使用嵌入式指针:也就是指针临时借用一下空闲块里的空间,等到需要分配出去使用时就正常使用即可。
        下面的rep和next占用同一片空间

        class A
        {
        private://数据struct Airplane//占8字节{int miles;char type;};
        private:union{Airplane rep;A* next;};static A* freeStore;//指向链表的头部的指针static const int Chunk = 3;//内存池容纳几个
        public:static void* operator new(size_t size);static void operator delete(void* ptr);void set(int m, char t)....void show()....
        };
        
    • 重载局部的operator delete()
      • 采用头插法,将空闲块插入到链表头
        void A::operator delete(void* ptr)
        {cout << "局部delete" << endl;//头插法static_cast<A*>(ptr)->next = A::freeStore;A::freeStore = static_cast<A*>(ptr);
        }
        
    • c语言版本的内存池
      • 先写个宏定义
        #define malloc(mp, size) _malloc(mp, size)
        #define free(mp, ptr) _free(mp, ptr)
        
      • 定义一个大的内存块,这里称其为页
        typedef struct mempool_s
        {int block_size;//一小块的大小int free_count;//该页内剩余空闲块的个数void *mem;//指向该页首地址void *ptr;//指向该页中最新创建的块的地址(即下次要分配出去内存的块)
        } mempool_t;
        
      • 写一个内存池初始化函数,将128个小块串成链表
        int memp_init(mempool_t *mp, size_t block_size)
        {printf("block_size: %ld\n", block_size);if (!mp) return -1;memset(mp, 0, sizeof(mempool_t));mp->block_size = block_size;mp->free_count = MEM_PAGE_SIZE / block_size;mp->mem = malloc(MEM_PAGE_SIZE);if(!mp->mem) return -1;mp->ptr = mp->mem;//把该页中的128块串成链表char *ptr = mp->ptr;//ptr指针指向第1块for (int i = 0; i < mp->free_count; i++){//使用2级指针:一级指针ptr,(char**)ptr将其强转为指向char*的指针,//*(char**)ptr为其指向的char*地址,将该地址赋值为ptr所指块的下一块地址*(char**)ptr = ptr + block_size;ptr += block_size;}*(char**)ptr = NULL;//最后一块的前几个字节保存的是NULLreturn 0;
        }
        
    • 最后写内存分配与释放的函数即可。释放时同样使用头插法

- G2.9 alloc的大致流程:page8

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

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

相关文章

Vue3 使用 Vue Router 时,params 传参失效

前言&#xff1a; 在写项目的时候&#xff0c;使用了 vue-router 的 params 进行传参&#xff0c;但是在详情页面中一直获取不到参数。原因&#xff1a;Vue Router 在2022-8-22的那次更新后&#xff0c;使用这种方式在新页面上无法获取&#xff01; 正文&#xff1a; 在列表页进…

虚拟机装入kali linux

VMware 首先需要先安装VMware Workstation Pro可以根据这篇文章来下载VMware 下载kali linux Installer Images VS Virtual Machines Installer Images&#xff08;安装镜像&#xff09;Virtual Machines&#xff08;虚拟机&#xff09; 直接访问硬件&#xff0c;定制内核…

Matlab|【防骗帖】考虑时空相关性的风电功率预测误差建模与分析

目录 1 主要内容 2 部分程序 3 下载链接 1 主要内容 这个程序《考虑时空相关性的风电功率预测误差建模与分析》画的图片非常漂亮&#xff0c;和原文献基本一致&#xff0c;但是实际上内容并未实现出来&#xff0c;主要就是利用现有的风电预测的数据和结果做了相关的图&#…

【数据结构】(C语言):链表

链表&#xff1a; 基本单位是节点。节点至少两部分&#xff1a;数据&#xff0c;下一个数据的地址。头指针head&#xff0c;始终指向链表的第一个节点。若没有节点&#xff0c;则headNULL。链表在内存中是非连续的。不能使用索引&#xff08;下标&#xff09;查找元素。只能从…

解决:Xshell通过SSH协议连接Ubuntu服务器报“服务器发送了一个意外的数据包,received:3,expected:20”

下图所示&#xff1a; 日志也基本看不出来问题在哪&#xff0c;只是说断开了连接大概是验证失败。有幸在某论坛评论区找到了原因&#xff0c;是因为我的xshell版本太低了而服务器的ssh版本太高&#xff0c;高版本的ssh默认屏蔽了一部分不太安全的算法导致建立连接的时候验证失败…

C++ 14新特性个人总结

variable templates 变量模板。这个特性允许模板被用于定义变量&#xff0c;就像之前模板可以用于定义函数或类型一样。变量模板为模板编程带来了新的灵活性&#xff0c;特别是在定义泛化的常量和元编程时非常有用。 变量模板的基本语法 变量模板的声明遵循以下基本语法&am…

解决Vue+Vite打包后Leaflet的marker图标不显示的问题

前言 用Leaflet写关于WebGIS的开发&#xff0c;用Vite或者webpack打包&#xff0c;打包后会找不到图标&#xff0c;如下所示。 直言的说&#xff0c;笔者去网上搜了搜&#xff0c;其实收到一个比较好是答案。网址如下。 &#xff08;完美解决~&#xff09;关于VueLeaflet添加…

eslint 与 prettier 的一些常见的配置项(很详细)

目录 1、eslint 常见配置项&#xff08;语法规范&#xff09; 2、 prettier 常见的配置项&#xff08;格式规范&#xff09; 代码规范相关内容看小编的该文章&#xff0c;获取对你有更好的帮助 vsCode代码格式化&#xff08;理解eslint、vetur、prettier&#xff0c;实现格式…

IDEA启动报错:Abnormal build process termination...

一、问题描述 因为项目需要&#xff0c;同时打开了两个idea&#xff0c;突然发现一个启动的时候报错&#xff0c;有点莫名其妙&#xff0c;刚还好好的&#xff0c;为啥就不能用了&#xff0c;一顿百度找方法&#xff0c;试了各种方法&#xff0c;像重新安装jdk、重启系统发现都…

TensorFlow开源项目

欢迎来到 Papicatch的博客 文章目录 &#x1f349;TensorFlow介绍 &#x1f349;主要特点和功能 &#x1f348;多语言支持 &#x1f348;灵活的架构 &#x1f348;分布式训练 &#x1f348;跨平台部署 &#x1f348;强大的工具链 &#x1f348;丰富的社区和生态系统 &a…

Vue3基础使用

目录 一、创建Vue3工程 (一)、cli (二)、vite 二、常用Composition API (一)、setup函数 (二)、ref函数 (三)、reactive函数 (四)、setup注意事项 (五)、计算属性 (六)、watch (七)、watchEffect函数 (八)、生命周期 1、以配置项的形式使用生命周期钩子 2、组合式…

【机器学习-10】 | Scikit-Learn工具包进阶指南:Scikit-Learn工具包之支持向量机模块研究

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

高考填报志愿攻略,5个步骤选专业和院校

在高考完毕出成绩的时候&#xff0c;很多人会陷入迷茫中&#xff0c;好像努力了这么多年&#xff0c;却不知道怎么规划好未来。怎么填报志愿合适&#xff1f;在填报志愿方面有几个内容需要弄清楚&#xff0c;按部就班就能找到方向&#xff0c;一起来了解一下正确的步骤吧。 第…

入局AI手机 苹果公布Apple Intelligence

日前&#xff0c;苹果WWDC 2024如期召开。在这持续1个小时44分钟的开发者大会上&#xff0c;苹果在前一个小时里更新了iOS、iPadOS、MacOS等操作系统&#xff0c;而且还首次更新了visionOS。余下的时间全部留给了苹果的“AI大礼包”——Apple Intelligence&#xff08;苹果智能…

mysql是什么

mysql是什么 是DBMS软件系统&#xff0c;并不是一个数据库&#xff0c;管理数据库 DBMS相当于用户和数据库之间的桥梁&#xff0c;有超过300种不同的dbms系统 mysql是关系型数据库&#xff0c;关系型数据库存储模型很想excel&#xff0c;用行和列组织数据 sql是一门编程语言…

关于ip地址的网页无法访问navigator的gpu、媒体、蓝牙等设备的解决方法

在使用threejs的WebGPURenderer渲染器时&#xff0c;发现localhost以及127.0.0.1才能访问到navigator.gpu&#xff0c;直接使用ip会变成undefined,原因是为了用户的隐私安全&#xff0c;只能在安全的上下文中使用&#xff0c;非安全的上下文就会是undefined&#xff0c;安全上下…

谷歌云(GCP)4门1453元最热门证书限时免费考

谷歌云(GCP)最新活动&#xff0c;完成免费官方课程&#xff0c;送4门最热门考试免费考试券1张(每张价值200刀/1453元)&#xff0c;这4门也包括最近大热的AI/ML考试&#xff0c;非常值得学习和参加&#xff0c;活动7/17截止 谷歌云是全球最火的三大云计算厂商(前两名AWS, Azure…

MySQL索引优化解决方案--索引失效(3)

索引失效情况 最佳左前缀法则&#xff1a;如果索引了多列&#xff0c;要遵循最左前缀法则&#xff0c;指的是查询从索引的最左前列开始并且不跳过索引中的列。不在索引列上做任何计算、函数操作&#xff0c;会导致索引失效而转向全表扫描存储引擎不能使用索引中范围条件右边的…

【Linux】进程信号_1

文章目录 八、进程信号1.信号 未完待续 八、进程信号 1.信号 信号和信号量之间没有任何关系。信号是Linux系统提供的让用户/进程给其他进程发送异步信息的一种方式。 常见信号&#xff1a; 当信号产生时&#xff0c;可选的处理方式有三种&#xff1a;①忽略此信号。②执行该…