c++内存管理_复习

news2024/11/25 6:46:10
  • 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;//最后一块的前几个字节保存的是NULL
            return 0;
        }
        
    • 最后写内存分配与释放的函数即可。释放时同样使用头插法

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

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

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

相关文章

一文2000字记录基于jmeter+perfmon的稳定性测试

01、任务情况 1、任务总览 本次平台稳定性测试的目的在于&#xff1a;在服务器压力处于较饱和&#xff08;达到80%系统最大TPS&#xff09;压力之下&#xff0c;在较长时间&#xff08;>8小时&#xff09;之内观测服务器稳定性问题&#xff0c;以及资源使用情况和异常。 …

清科ZF引导基金数据(1990-2023年)

清科ZF引导基金数据&#xff0c;参考经济学家吴超鹏和严泽浩在《经济研究》2023年的研究&#xff0c;通过清科私募通数据库&#xff0c;获取ZF引导基金的管理机构信息。数据涵盖了ZF引导基金的关键信息&#xff0c;如基金名称、管理机构详情、所属层级、发展阶段、地域分布、初…

渗透测试之SQL注入

渗透测试之SQL注入 1. SQL注入分类 按照攻击类型分为&#xff1a;联合查询注入、布尔注入、时间延迟注入、报错型注入、堆叠型注入等 按照注入位置分为&#xff1a;HTTP头注入、请求参数注入等 按照数据库场景分为&#xff1a;MySQL注入、MSSQL注入、Oracle场景注入 1. My…

【D3.js in Action 3 精译】1.1.2 D3.js 的适用场景

译注 上一节中我们了解了 D3 诞生的技术背景——为了满足 Web 可访问数据的可视化需求。本节再来看看 D3.js 的适用场景是怎样的、在什么时候会考虑使用 D3.js。 1.1.2 D3.js 的适用场景 数据可视化领域正蓬勃发展&#xff0c;且备受青睐。过去十年间用于生成数据驱动图形的工…

中小学劳技课程开展创意木工 传承非遗木工魅力

学生劳技课程&#xff0c;全称劳动技术课程&#xff0c;是一门旨在通过实践活动培养学生的劳动技能、创新思维、实践能力和社会责任感的基础教育课程。这门课程强调学生的参与和体验&#xff0c;让学生在动手实践中学习并掌握知识&#xff0c;提高解决问题的能力。 学生劳技课程…

Charles抓包工具系列文章(四)-- Rewrite 重写工具

一、背景 这是一款比Map Local/Remote 还强大的工具&#xff0c;更加灵活&#xff0c;体现在以下几点&#xff1a; 重写request报文重写response报文header 字段的增删改query param 字段的增删改重写 body 字段改写http 响应状态status重写host/url/path 从这也可以看出其强…

【链表经典算法OJ题】(2)

4.链表的中间节点 单链表相关经典算法OJ题4&#xff1a; 链表的中间结点 . - 力扣&#xff08;LeetCode&#xff09;. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problem…

计算机网络之入门

1.网络的发展 1.1计算机网络定义 计算机网络是以共享资源&#xff08;硬件、软件和数据等&#xff09;为目的而连接起来的、在协议控制下&#xff0c;由一台或多台计算机、若干台终端设备、数据传输设备等组成的系统之集合。 这些计算机系统应当具有独立自治的能力&#xff…

关于导入springcloud项目一些jar加载不进去的问题处理

IntelliJ IDEA的Maven项目有时候通过右边Maven Projects面板的package或者install命令打包的时候&#xff0c;会报错导致打包失败&#xff0c;这是由于这两个命令打包前默认会运行tests测试&#xff0c;若测试失败则打包失败。但是有时候我们打包的时候一些项目配置是针对生产环…

SpringCloud Alibaba Seata2.0基础入门与安装

官网地址&#xff1a;https://seata.apache.org/zh-cn/ GitHub下载地址&#xff1a;https://github.com/apache/incubator-seata/releases 本文这里下载的是seata2.0.0版本。 【1】概述 ① Seata是什么 Simple Extensible Autonomous Transaction Architecture&#xff0c…

【代码】c++几个常用的函数

Hello!大家好&#xff0c;我是学霸小羊&#xff0c;今天讲讲c函数库里面的几个基本函数。 1.sort() sort()是大名鼎鼎的排序函数&#xff0c;以前起码一两个循环的排序&#xff0c;用这个函数一行代码就可以解决。 格式&#xff1a; sort(数组名""开始下标&#…

iOS开发者模式自带弱网测试工具

弱网测试的思路 弱网功能测试&#xff1a;2G/3G/4G、高延时、高丢包 无网状态测试&#xff1a;断网功能测试、本地数据存储 用户体验关注&#xff1a;响应时间、页面呈现、超时文案、超时重连、安全及大流量风险 网络切换测试&#xff1a;WIFI → 4G/3G/2G → 网多状态切换…

高考填报志愿,为何要优先考虑个人兴趣 ?

随着高考成绩纷纷出炉&#xff0c;考生又要面对人生另外一个重要的选择&#xff0c;那便是填报志愿&#xff0c;这关系到自己能否进入满意的学校和专业。如果考生对上述两个方面都不满意&#xff0c;那高考目的就没有达到。既然填报志愿如此重要&#xff0c;考生和家长在选择的…

MFC案例:自制工具条(Toolbar)按钮的小程序

程序目标&#xff1a;在基于对话框的MFC项目中&#xff0c;自制三个 Toolbar 按钮&#xff08;用颜色区分&#xff0c;分别为红、绿、蓝&#xff09;&#xff1b;程序运行时&#xff0c;单击红色按钮显示一个红色的填充椭圆&#xff1b;再单击绿色按钮则进行清屏&#xff1b;最…

【YOLO 系列】基于YOLO V8的密集场景下行人检测识别系统【python源码+Pyqt5界面+数据集+训练代码】

前言 在密集的城市环境中&#xff0c;行人检测对于公共安全、交通管理和智能监控具有重要意义。然而&#xff0c;传统的行人检测方法在面对密集场景时&#xff0c;常常因目标重叠和遮挡而难以准确识别。为了应对这一挑战&#xff0c;我们启动了这个项目&#xff0c;目的是利用…

江苏隆昌化工上线隆道平台 采购管理迎来全面升级

当前&#xff0c;传统产业与数字产业深度加速融合&#xff0c;大数据、云计算、人工智能等新技术推动产业深刻变革&#xff0c;能源化工行业迎来战略转型加速期。数字化转型已成为能源化工企业提升运营效率、控制运营成本、提高产品质量、打造竞争优势的强大引擎。为实现传统采…

OVS:网桥的状态:fail_mode模式

目录 1.创建一个普通的ovs网桥不做任何配置 2.检测fail_mode值&#xff0c;默认为空 3.创建netns并配置sto网桥的两个普通端口并配置IP信息 4.默认情况下的两个端口下挂两个虚拟机v3,v4天然通信-ping-ok 5.修改网桥的fail_mode为standalone,原来的通信没有影响 6.修改了…

java常用类(1)

目录 1.Object类 1.1 toString()方法 1.1.1重写toString()方法 2.1 equals()方法 2.1.1 的作用 2.1.2 equals()方法 2.Arrays类 2.1 equals()方法 2.2 copyOf()方法 2.3 fill()方法 2.4 sort()方法 1.Object类 在java中Object类是所有类的父类,如果一个类没有显示…

数据独立性-信息、数据、数据结构、数据独立性

一、引言 同人工管理数据和文件系统管理数据相比&#xff0c;数据库管理数据最主要的优点是数据独立性高。数据独立性是数据库领域中的一个常用术语和重要概念&#xff0c;包括数据的物理独立性和逻辑独立性 二、数据与数据结构 1、信息 在数据管理领域&#xff0c;数据与信…

排序之插入排序----直接插入排序和希尔排序(1)

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 排序之插入排序----直接插入排序和希尔排序(1) 收录于专栏【数据结构初阶】 本专栏旨在分享学习数据结构学习的一点学习笔记&#xff0c;欢迎大家在评论区交流讨…