C++之动态内存管理

单片机的动态内存管理——自己实现heap管理 两年前一位同事和我说过,单片机不能实现动态内存管理,两天后我在keil上利用malloc()在coterx m3芯片上实现了一个链表,然后把代码给他看了,对固执的人摆事实好过讲道理。之后我觉得使用malloc()并不能满足我的需求,然后想自己实现一个heap管理。这就是这篇文章的由来,这是我今天下午突然想到的一种简单的方法,其实这很没有意义,因为我能想到的东西,别人都已经做出来了。嗯,姑且当是一个... 阅读详情

想必很多学习C++的人都有很深厚的C语言基础.
在C语言中,我们是用malloc,calloc,realloc三位男士和free一位女士来动态管理内存的
先coding一下C语言的基本动态内存管理模式
void RAMManageByC()
{
int ptr1=(int)malloc(sizeof(int));//申请大小为sizeof(int)大小的内存,不进行初始化
int* ptr2=(int*)malloc(sizeof(int)n);//申请长度为n的整形数组,不进行初始化
int
ptr3=(int*)calloc(n,sizeof(int));申请n个大小为sizeof(int)的整形变量,并且将其初始化为0
int* ptr4=(int*)realloc(ptr2,sizeof(int)n);//在ptr2后边继续申请n个sizeof(int)的空间,不进行初始化
free(ptr2);
free(ptr3);
free(ptr4);//这里不需要释放ptr1,因为释放ptr4的同时也已经释放了ptr1所申请的内存空间,如果再释放,就会导致二次释放的问题
}
然而这种初始化方式是有很大的缺陷的
首先它的初始化非常的难受,malloc申请的内存空间需要手动去初始化,calloc申请的内存空间虽然名义是初始化的,但是它不一定能按照我的意愿去进行初始化,realloc和malloc相同,这大大降低了我们程序猿的幸福感
然而,这还不是最坑的,请看下边的栗子
class Date{
public:
Date(int year,int month,int day)
: _year(year),_month(month),_day(day)
{}
~Date()
{}
private:
int _year;
int _month;
int _day;
};
void testC()
{
Date ptr=(Date)malloc(sizeof(Date));
//然而这里它仅仅是申请了sizeof(Date)这麽大的空间,并没有对其内部成员进行初始化操作,非常之难受
}
现在我们既然来到了C++世界,就让我们看下一种新的动态内存管理的方式
void RAMManageByCPlusPlus()
{
int
ptr1=new int;//申请一个int类型变量的内存空间,不对其进行初始化操作
int* ptr2=new int(3);//申请了一个int类型的变量的内存空间,并将其大小初始化为3
int* ptr3=new int[3];//申请一个长度为3的int类型数组,不进行初始化
//唯一尴尬的就说new在申请连续内存的时候无法进行初始化
delete ptr1;//释放单个内存空间
delete ptr2;
delete[] ptr3;//释放连续的内存空间
}
对内置类型的变量申请内存说完以后,我们再来谈谈自定义类型
就比如对上面的日期类
void testCPlusPlus()
{
Date* ptr=new Date(2020,3,20);//申请一个Date类型的变量,并调用构造函数对其进行初始化
Date* ptr1 = new Date[10];
//申请一个大小为10的Date类型的数组
//然而,这里编译器是会报错的
//为啥呢,因为用new来申请内存空间的时候,是会调用默认构造函数的,而Date类事实上并没有默认构造函数,所以程序势必凉凉.
delete ptr;//先调用析构函数释放资源,然后再回收对象空间
datele []ptr1;//和上边相同
}
事实上对于我们的自定义类型,new和delete在管理内存的时候,会调用构造函数/析构函数,而malloc和free则不会
对于malloc,free,new,delete的使用需要注意的是
1.malloc/free,new/delete在使用上一定要对应起来
2.malloc和delete在使用时候,类似于函数调用,而我们的new /delete却不然
,事实上,new 和 delete只是关键字,它们并不是函数
我接下来在介绍两个重要的全局函数
void* operator new(unsigned int n)
void operator delete(unsigned int n)
值得一提的是,他们不是运算符重载函数
而是系统全局函数
事实上new和delete在底层就说通过这两个函数来实现内存申请和销毁工作的
当然我们也可以直接调用他们来完成内存的申请和释放工作
下边我们先研究一哈void* operator new(size_t n)//size_t和unsigned int一个意思,这个想必大家都知道
比如说申请以一个大小为sizeof(int)的空间
int* ptr=(int*)malloc(sizeof(int))
int* ptr1=(int*)operator new(sizeof(int))
这个使用方法确实和malloc一个模打出来的
事实上,它的底层就是调用malloc函数来完成的
我们都知道malloc函数调用失败的时候会返回NULL
但是operator new并不是这样的
它当malloc申请内存失败时会尝试空间不足的应对措施,如果该应对措施可以解决内存不足的问题,那么它会继续尝试申请,否则会抛出异常
对于new申请自定义类型变量,它走的流程是:
operator new—>构造函数
下边我们说一下void operator delete(void*)
正如大家所想象的那样子,delete也是一个全局函数,它的底层实际上是调用了free
对于自定义类型对象的释放,当我们用delete释放自定义类型对象时走的流程就是析构函数 ->> void operator delete(void*)
写到这里,我们可以发现一个问题
就是我们每次申请内存都要消耗时间,当然申请次数少不要紧,频繁的话实际上是会影响性能的
事实上计算机给我们想了一种特别好的办法去解决这个问题
就说内存池的思想
什么是内存池呢,事实上,内存池就说一个备胎,计算机并不是一次只申请你所要的那些内存,而是申请了很多,当你用的时候再从池子里边拿就可以,这样就大大的优化了内存申请的开销,我们都知道链表是经常会申请内存的,现在我写一个链表的类operator new重载函数帮助理解一下内存池的思想
class Node{
Node()
{}
void* operator new(size_t n)
{
//内存池申请
void* ptrallocator().allocate(1);
return ptr;
}
//内存池释放
void operator new(void* p)
{
allcator().deallocate((Node* ptr,1));
}
};
我再说一个显示调用构造函数的方法
void test()
{
Date* ptr=(Date*)malloc(sizeof(Date));//申请内存空间
new (ptr) Date(2020,10,30);//完成对自定义类型的初始化
语法就是new(初始化空间的地址)类型(参数列表)
}
最后再说一下申请了内存不是放的后果(内存泄漏)
我们写的程序会在运行结束的时候去释放空间资源,对于运行时间很短,而且申请空间不大的程序来说,比如说我们经常写的程序,这确实不是很要紧,但是对于一个服务器来说,它实际上是全天24小时运行的,如果有内存泄漏,就会造成内存不够用的情况,从而导致服务器程序彻底崩溃,因此内存泄漏在实际工作中是绝对不可以发生的,因此我们在使用new malloc申请的内存一定要及时的释放

C/C++动态内存管理 C/C++中的动态内存管理是指在程序运行时,根据需要动态地分配和释放内存空间。这种管理方式主要通过堆(Heap)内存来实现,与栈(Stack)内存不同,堆内存的分配和释放不由编译器自动管理,而是需要程序员手动控制。以下是C/C++动态内存管理的详细介绍:在C++中,动态内存分配主要通过和操作符来实现,而在C语言中,则使用、、和等函数。 calloc: 用于分配多个相同大小的内存块,并将其初始化为零。 realloc: 用于重新分配已分配的内存块的大小。 free: 用于释放之前通过、或分配的内 阅读详情

相关推荐

深入详解C/C++动态内存管理

本文详细讲述了C/C++动态内存管理方面的内容,并具体阐述了几类常见的动态内存异常,以供大家借鉴或参考!

dvlinker的技术专栏 2万+

C++ STL中的自定义Allocator

来源: http://www.cnblogs.com/wpcockroach/archive/2012/05/10/2493564.html> 说一说C++里的allocator。我们知道,C++ STL里定义了很多的容器(containers),每一个容器的第二个模板参数都是allocator类型。比方说在VC10里,vector类的模板声明为: template > cla

Invoker's Tower 1万+

S7-1200与KINCO伺服通信实战:CM CANopen模块配置避坑指南(附完整PDO映射表)

本文详细解析了西门子S7-1200 PLC通过CM CANopen模块与KINCO伺服驱动器的通信配置全流程,重点解决PDO映射混乱、心跳报文配置错误等常见问题。提供硬件组态、参数设置、PDO映射模板及故障排查方案,助力工业自动化系统实现稳定高效的多轴运动控制。

2y3u4i5o6p的博客 1100

C++动态内存分配---allocator类的原理与实现(一)

包装标准库函数operator new和delete 实现了简单的allocator类,并与默认allocator类对比

wutao1530663的博客 4712

东方财富网 数据访问接口及字段说明

东方财富网 数据访问接口和字段说明

雨中山草 2万+

使用下一代的嵌入式IDE-PlatformIO 教程

1.生成工程 1.1 打开STM32CubeMX: 选择你的MCU,这里我用的是STM32F103RC RCC中开启外部HSE时钟,外部时钟比HSI更稳定些 开启DEBUG 4线 打开串口1用于打印调试信息,波特率115200,校验位0,停止位1 打开串口2用于MODBUS协议,波特率9600,校验位0,停止位1 接入RT-thread:参考官方文档 基于 CubeMX 移植 RT-Thread Nano 根据官方文档,需要1.取消生成HardFault_Handler、PendSV_Handler、Sy

jiladahe1997的博客 3万+

C++ allocator 自定义指南

闲话 昨天培神在群里抱怨说自定义allocator遇到了奇怪的问题,然后选择了pmr,我表示很理解。allocator这个东西,出生时就伴随着设计错误和无用的抽象,C++03-14糊了这么久,甚至还加了新feature来兼容旧翔和糊新翔,结果C++17最终还是另立门派搞了个pmr。 简单说,虽然allocator的concept说了很多东西,也有一些周边的concept比如alloc...

diaolongyun5218的博客 1126

用STM32F103单片机控制电调制动无刷电机

用电调控制无刷电机制作遥控飞艇 蓝牙控制 调控电调 无刷电机 用电调控制无刷电机制作遥控飞艇 代码区 mian.c #include "delay.h" #include "sys.h" #include "usart.h" #include "usart3.h" #include "timer.h" #include "led.h" #include "key.h" int main(v...

子非鱼 的博客 2万+

【c++】动态内存管理

1. new:首先调用operator new函数申请内存空间,然后调用构造函数,完成初始化2. delete:首先调用析构函数,对开辟的内存进行资源清理,然后调用operator delete函数释放内存3. new[]:首先调用 operator new[ ] 函数申请多个对象的内存空间(该函数中调用了operator new),然后调用N次构造函数,完成初始化。

2301_80955819的博客 1738

EBOM转MBOM实战:华为云数字工厂如何5步搞定BOM自动转换(含避坑指南)

本文详细解析了华为云数字工厂平台如何通过五步自动化流程实现EBOM到MBOM的高效转换,涵盖模型预配置、逻辑流编排、工艺属性注入等关键步骤,并提供了多工厂差异化配置、历史数据迁移等典型场景的避坑指南。该方案显著提升转换效率,降低差错率,助力企业实现数字化转型。

weixin_29215391的博客 268

ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: NO)解决办法

问题:ERROR 1045 (28000): Access denied for user ‘root’@‘localhost’ (using password: NO) 很久没用这台电脑的mysql了,今天需要连接数据库,启动数据库报错: ERROR 1045 (28000): Access denied for user ‘root’@‘localhost’ (using password: NO) 解决方法: 查阅资料后知道了,应该使用已知的用户名和密码登陆 mysql -u root -p 然而密

一个超会写Bug的程序猿的博客 43万+

【C++】动态内存管理

介绍了内存分布、new delete 操作符及其底层原理和拓展操作

HDSTQTW的博客 1256

基于单片机红外线遥控Proteus仿真电路发射接收

*单片机设计介绍,基于单片机红外线遥控Proteus仿真电路发射接收。

2201_75940997的博客 3942

【带你吃透C++】C++动态内存管理

作为一名编程初学者,通常学习中,发生内存错误是件非常麻烦的事情。编译器不能自动发现这些错误,通常是在程序运行时才能捕捉到。而这些错误大多没有明显的症状,时隐时现,增加了改错的难度。 了解内存分配并掌握运用它是必不可少的。本文主要针对C++动态内存管理内容进行分享,如果想了解C语言动态内存管理可以参考:【C语言进阶】动态内存管理(详细介绍)

平淡中造就不平凡 7076

YOLOv8深度集成SDFM:显著增强特征细节与多尺度融合,实现小目标检测革命性提升

本文介绍了如何将SDFM(Superficial Detail Fusion Module)模块集成到YOLOv8目标检测模型中,以提升特征融合效能。SDFM通过精细的特征预校准、通道注意力机制和动态加权融合策略,有效解决了多尺度特征融合中的细节保留问题。实验表明,集成SDFM后YOLOv8的mAP50-95提升12.7%,召回率提升9.0%,精确率提升5.9%,显著增强了模型性能。教程详细阐述了SDFM的工作原理、代码实现步骤及优化思路,为研究者和开发者提供了实用的技术指南。

FJN110的博客 117

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

【C/C++】动态内存管理

malloc calloc realloc free 柔性数组

凤年徐的博客 4836

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

C++动态内存管理

C++动态内存管理

2301_76269963的博客 776

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

【C++修炼之路】C++动态内存管理

C语言的malloc/free如同原始人的燧石,C++用new/delete将其淬炼为青铜利刃

m0_74779094的博客 1021

CPP之动态内存管理以及模板初阶

(他们在对内置类型进行创建的时候基本上没有区别)。

zyzyzy_mhmhmh的博客 942

C和Cpp里面的动态内存管理

c动态内存管理c语言里面的动态内存管理函数,介绍的有4个,分别是malloc, realloc,calloc,和free,其函数原型分别如下void *malloc(size_t size); void *calloc(size_t num_elements,size_t element_size); void realloc(void ptr,size_t new_size); void

681

青龙面板 + QLScriptPublic 指南:如何 5 分钟部署一套 100+ 的自动化签到脚本

早上九点的电梯里、通勤地铁上、午休的工位前——你大概也有过这样的时刻:手机里躺着一二十个 App 和小程序,每个都藏着"每日签到""积分任务""浏览赚金币",手动点一遍少说十几分钟,隔天再点又是一遍,漏一天还断了连续签到。QLScriptPublic 配合青龙面板做的,就是把这类重复劳动交给脚本定时执行:你只负责把账号信息填一次,剩下的交给 cron。这个仓库目前收拢了 100 多个可用脚本,覆盖

gitblog_00937的博客 915

C++——动态内存管理

C++——动态内存管理

qq_47222034的博客 1263
上一篇: 面向对象(OOP)思想3
下一篇: mciSendString函数播放mp3音乐,这里直接给大家上代码
ldbite
博客等级 码龄7年 17粉丝 195原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值