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万+

安卓app逆向破解脱壳教程

From:Hook 神器家族的 Frida 工具使用详解:https://blog.youkuaiyun.com/FlyPigYe/article/details/90258758 详解 Hook 框架 frida (信抢红包):https://www.freebuf.com/company-information/180480.html APP逆向神器之Frida【Android初级篇】:https://www.jianshu.com/p/2d755beb1c54 frida 官网文档:https://fr..

sinat_28371057的博客 2万+

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

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

wutao1530663的博客 4712

ANSYS APDL学习(6):ANSYS APDL部分命令流介绍

介绍APDL 部分命令流

娱乐至上的博客 1万+

408王道计算机组成原理强化——指令系统及大题解构

1.大纲要求 2.x86

JiangNan_1002的博客 8511

C++ allocator 自定义指南

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

diaolongyun5218的博客 1126

OpenMMLab实战指南:从环境搭建到首个检测模型运行

本文是一份详细的OpenMMLab实战指南,重点介绍了如何从零开始搭建环境并运行首个目标检测模型。内容涵盖Miniconda环境配置、PyTorch与CUDA版本匹配、使用MIM工具安装MMCV和MMDetection的核心步骤,并通过RTMDet-tiny模型演示了完整的推理流程,帮助开发者高效入门这一计算机视觉开源算法体系。

weixin_28678151的博客 155

【c++】动态内存管理

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

2301_80955819的博客 1738

KEPServerEX物联网网关(IoT Gateway)REST客户端代理(非原创)

(中文版)资料来源于【OPC-KEPServerEX学习KEPWare交流】905485143群的【455196383】【零下一度】 一。KEPServerEX物联网网关REST客户端代理演示 在KSE中,首先构建一个带有通道/设备/标签的模拟器系统。 例如,下面是三个随机项目。 直接到IoT网关插件,添加新代理。 从类型列表中选择REST Client。 终结点...

-雲飛兄-博客 5806

Oracle11g下载与安装(windows)

一、Oracle11g下载 二、安装准备 三、执行安装步骤 四、测试连接 附:Oracle11g服务说明

欢迎订阅我的“JAVA全栈开发笔记(全)”专栏,价格优惠,仅需19.9元。 2万+

【C++】动态内存管理

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

HDSTQTW的博客 1256

CH7034B显示模块原理图设计,已量产

显示桥接板的价值,不在于简单把 RGB 排线换成另一种接口,而在于能否把并行视频、时钟、显示控制、模拟输出和辅助配置同时组织成稳定系统。当前这张 CH7034B 原理图就是这种思路:U3 CH7034B 作为核心桥接芯片,输入侧是 LCD_R0~R7、LCD_G0~G7、LCD_B0~B7、LCD_DE、LCD_HSYNC、LCD_VSYNC、LCD_CLK 与 LCD_BL,输出侧则通过 DAC0~DAC2 和 DDC_SC/DDC_SD 形成模拟显示接口边界。

不脱发的程序猿 161

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

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

平淡中造就不平凡 7076

【数据集8】全球人口数据WorldPop详解

全球人口数据WorldPop详解

WW、forever的博客 7879

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

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

malloc calloc realloc free 柔性数组

凤年徐的博客 4836

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

C++动态内存管理

C++动态内存管理

2301_76269963的博客 776

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

【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、付费专栏及课程。

余额充值