C++内存管理(区别C语言)深度对比
欢迎来到我的Blog,点击关注哦💕
前言
前面已经介绍了类和对象,对C++面向对象编程已经有了全面认识,接下来要学习对语言学习比较重要的是对内存的管理。
一、内存的分区
- 代码区:存放程序的机器指令,通常是可共享的,并且通常为只读的,以防止程序意外修改自身的代码。
- 全局/静态存储区:存放全局变量和静态变量,这些变量在程序的整个生命周期内都存在。
- 堆区:用于动态分配内存,程序运行时根据需要通过malloc、calloc、realloc等函数在堆区中分配内存空间。
- 栈区:存放函数的局部变量和函数调用的参数,由编译器自动管理,遵循后进先出的原则。
- 常量区:存放常量数据,如字符串字面量,这些数据在程序运行期间不可修改。
- 代码区:存放程序的二进制代码,是程序执行指令的存储空间。

二、C语言中的内存管理(参考)
malloc函数用于动态分配指定大小的内存空间,并返回指向该内存的指针。如果分配成功,返回非NULL指针;否则返回NULL。calloc函数除了分配内存外,还会将分配的内存初始化为零。realloc函数用于调整已分配内存的大小,可能会移动内存块以适应新的大小要求。free函数用于释放之前通过动态内存分配函数分配的内存空间
三、C++中的内存管理
C++内存分配
不同于C语言,C++有着自己独立动态内存开辟的方法:
主要通过new和delete操作符来实现。new操作符用于分配单个对象或数组,而delete和delete[]分别用于释放这些对象或数组所占用的内存.
下面是new和delete应用的实例:
//动态申请一个int大小空间
int* p0 = new int;
//动态申请一个int大小空间并且初始化为0
int* p1 = new int (0);
//动态申请10个int大小空间
int* p2 = new int[10];
//动态申请10个int大小空间并且初始化为0
int* p3 = new int[10] {0};delete p0;
delete p1;
delete[] p2;
delete[] p3;
注意
- 不要使用delete释放非new开辟的空间
- 不要使用delete释放同一块空间两次
- 如果使用new [ ] 开辟数组进行内存分配,应该使用delete [ ] 来释放
- 如果new对一个实体进行内存分配,应该使用delete(没有方括号)进行释放
四、new 和 delete深度探索
有关operator new 和operator delete
operator new
-
operator new是一个特殊的操作符,用于动态分配内存。它与new操作符密切相关,但它们在语义上有所区分。 -
new操作符是一个高级操作符,它不仅分配内存,还自动调用对象的构造函数。 -
operator new仅负责分配内存,不涉及对象的构造。 -
operator new可以被重载,以便为特定的类或全局范围提供自定义的内存分配策略 -
operator new:该函数实际通过``malloc来申请空间,当malloc`申请空间成功时直接返回 -
申请空间失败, 尝试执行空 间不足应对措施,如果改应对措施用户设置了,则继续申请,否则抛异常。
通俗的讲 ,new 不仅仅可以进行空间开辟,针对自定义类型会调用其构造函数,而new也是调用重载(operator new),进行内存的分配,然而 operator new 进行内存分配是通过malloc进行实现的,这正是区别于C语言的其中一点。
关于时间类和汇编语言:
class Date
{
public:Date(int year = 1,int month = 1,int day = 1):_year(year),_month(month),_day(day){}~Date(){_year = 0;_month = 0;_day = 0;}private:int _year = 1;int _month = 1;int _day = 1;
};Date* d1 = new Date;
00007FF62A0D19FC mov ecx,0Ch
00007FF62A0D1A01 call operator new (07FF62A0D103Ch) 。//调用operator new内存分配
00007FF62A0D1A06 mov qword ptr [rbp+108h],rax
00007FF62A0D1A0D cmp qword ptr [rbp+108h],0
00007FF62A0D1A15 je main+5Dh (07FF62A0D1A3Dh)
00007FF62A0D1A17 mov r9d,1
00007FF62A0D1A1D mov r8d,1
00007FF62A0D1A23 mov edx,1
00007FF62A0D1A28 mov rcx,qword ptr [rbp+108h]
00007FF62A0D1A2F call Date::Date (07FF62A0D13D4h) // 调用构造函数
00007FF62A0D1A34 mov qword ptr [rbp+118h],rax
00007FF62A0D1A3B jmp main+68h (07FF62A0D1A48h)
00007FF62A0D1A3D mov qword ptr [rbp+118h],0
00007FF62A0D1A48 mov rax,qword ptr [rbp+118h]
00007FF62A0D1A4F mov qword ptr [rbp+0E8h],rax
00007FF62A0D1A56 mov rax,qword ptr [rbp+0E8h]
00007FF62A0D1A5D mov qword ptr [d1],rax
operator delete
operator delete是一个全局函数,用于释放之前通过operator new分配的内存。- 它是
new操作符的逆运算,负责在内存释放时执行必要的清理工作。 operator delete通常在delete表达式中被隐式调用,用于释放单个对象或对象数组的内存- 在空间上执行析构函数,完成对象中资源的清理工作
- 调用operator delete函数释放对象的空间(通过free)
00B72150 push ebp 已用时间<=1ms
00B72151 mov ebp,esp
00B72153 sub esp,0cCh
00B72159 push ebx
00B7215A push esi
00B7215B push edi
00B7215C push ecx
00B7215D lea edi,[ebp-0Ch]
00B72160 mov ecx,3
00B72165 mov eax,0cccccccch
00B7216A rep stos dword ptr es:[edi]
00B7216C pop ecx
00B7216D mov dword ptr [this],ecx
00B72170 mov ecx,dword ptr [this]
00B72173 call A::~A (0B7154Bh) //调用析构函数
00B72178 mov eax,dword ptr [ebp+8]
00B7217B and eax,1
00B7217E je __call_empty_init_list_helper<A>+0Eh (0
00B72180 push 4
00B72182 mov eax,dword ptr [t. ebp 15990024
00B72185 push eax
00B72186 call operator delete (0B710AAh) //释放空间
00B7218B add esp,8
00B7218E mov eax,dword ptr [this]
00B72191 pop edi
00B72192 pop esi
小结
new 和delete 调用的时候内部调用的顺序
- new 先进行空间的开辟(
malloc),在进行对象的实例化 - delete先进行析构函数的调用,进行资源的销毁,在进行空间的释放(
free)
五、replacement new
在C++中new操作符通常用于在堆上分配内存并调用对象的构造函数。除了常规的new操作符外,C++还提供了operator new和placement new两种替代机制。operator new是new操作符内部使用的函数,可以被重载以提供自定义的内存分配策略。而placement new是一种特殊的new表达式,它允许在已分配的内存上构造对象,而不是分配新的内存。
//用法
new(place_address)type
应用场景:
池化技术:
化技术在C++编程中通常指的是预先分配一定数量的资源(如内存、线程等)并存储在一个“池”中,以便在程序运行时可以快速地从中获取和返回资源,而不是每次都进行昂贵的动态分配和释放操作。
这个就是进行已有空间进行对象实例化
六、C语言和C++内存分配的区别
区别malloc free new delete
malloc和free是函数,而new和delete是操作符malloc不可以初始化而new可以初始化malloc进行内存分配的时候是手动计算空间的大小,而new后面跟类型,大小在[ ]中指定malloc的返回值为void*,在使用时必须强转,new不需要,因为new后跟的是空间的类型malloc申请空间失败是返回NULL,而new申请空间失败是捕获异常- 申请自定义类型对象时,
malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间 后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理
为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型
5. malloc申请空间失败是返回NULL,而new申请空间失败是捕获异常
6. 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间 后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理
相关文章:
C++内存管理(区别C语言)深度对比
欢迎来到我的Blog,点击关注哦💕 前言 前面已经介绍了类和对象,对C面向对象编程已经有了全面认识,接下来要学习对语言学习比较重要的是对内存的管理。 一、内存的分区 代码区:存放程序的机器指令,通常是可…...
手把手带你写一个精简版 HashMap 的 put 方法
👆🏻👆🏻👆🏻关注博主,让你的代码变得更加优雅。 前言 HashMap 大家工作中遇到的太多了,已经成了必须使用的类了, 在面试的时候 HashMap 基本是必问题,但是…...
【面试题】数据结构:堆排序的排序思想?
堆排序的排序思想? 堆排序是一种高效的排序算法,其基本思想是利用堆这种数据结构来实现排序。堆是一种特殊的完全二叉树,通常用数组来表示。堆排序的基本步骤如下: 1. 构建初始堆: 将待排序的数组转换成一个最大堆&a…...
PyTorch 深度学习实践-循环神经网络基础篇
视频指路 参考博客笔记 参考笔记二 文章目录 上课笔记基于RNNCell实现总代码 基于RNN实现总代码 含嵌入层的RNN网络嵌入层的作用含嵌入层的RNN网络架构总代码 其他RNN扩展基本注意力机制自注意力机制(Self-Attention)自注意力计算多头注意力机制…...
vue实现可拖拽dialog封装
一、实现modal弹窗组件 <template><divv-if"visible"class"customer-dialog"id"customer-dialog":style"dialogStyles"v-dialogDrag:[dialogDrag]><div class"dialog-container"><divclass"dial…...
本地多模态看图说话-llava
其中图片为bast64转码,方便json序列化。 其中模型llava为本地ollama运行的模型,如:ollama run llava 还有其它的模型如:llava-phi3,通过phi3微调过的版本。 实际测试下来,发现本地多模型的性能不佳&…...
人工智能算法工程师(中级)课程14-神经网络的优化与设计之拟合问题及优化与代码详解
大家好,我是微学AI,今天给大家介绍一下人工智能算法工程师(中级)课程14-神经网络的优化与设计之拟合问题及优化与代码详解。在机器学习和深度学习领域,模型的训练目标是找到一组参数,使得模型能够从训练数据中学习到有用的模式&am…...
Java异常抛出与处理方法
在Java编程中,异常处理是一个非常重要的部分。通过正确的异常处理,我们可以提高程序的健壮性和可靠性,避免程序在运行过程中出现意外的崩溃。本文将详细讲述Java异常的抛出与处理方法,并通过示例代码进行说明。 一、Java异常的分类 Java中的异常体系结构可以分为三类: 检…...
兼容性测试主要有什么类型?
兼容性测试的类型 有两种类型的兼容性测试。这是一个快速细分。 1、前向兼容性测试 向前兼容性测试或向上兼容性测试可确保当前软件版本在相关组件(例如操作系统、浏览器和第三方库)的未来版本中保持功能。此类测试对于在系统升级期间保持稳定性和用户体验至关重要。 例如&…...
设计模式--组合模式
组合模式(Composite Pattern)详解 组合模式是一种结构型设计模式,它允许你将对象组合成树形结构来表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 适用场景 需要表示对象的部分-整体层次结构时&am…...
ArduPilot开源代码之AP_DAL_RangeFinder
ArduPilot开源代码之AP_DAL_RangeFinder 1. 源由2. 框架设计2.1 枚举 Status2.2 公有方法2.3 私有成员变量 3. 重要例程3.1 应用函数3.1.1 ground_clearance_cm_orient3.1.2 max_distance_cm_orient3.1.3 has_orientation3.1.4 get_backend 3.2 其他函数3.2.1 AP_DAL_RangeFind…...
SpringCloud教程 | 第九篇: 使用API Gateway
1、参考资料 SpringCloud基础篇-10-服务网关-Gateway_springcloud gateway-CSDN博客 2、先学习路由,参考了5.1 2.1、建了一个cloudGatewayDemo,这是用来配置网关的工程,配置如下: http://localhost:18080/aaa/name 该接口代码如…...
数据结构——hash(hashmap源码探究)
hash是什么? hash也称为散列,就是把任意长度的输入,通过散列算法,变成固定长度的输出,这个输出值就是散列值。 举例来说明一下什么是hash: 假设我们要把1~12存入到一个大小是5的hash表中,我们…...
国产麒麟、UOS在线打开pdf加盖印章
PageOffice支持两种电子印章方案,可实现对Word、Excel、PDF文档加盖PageOffice自带印章或ZoomSeal电子印章(全方位保护、防篡改、防伪造)。Word和Excel的盖章功能请参考:Word和Excel加盖印章和签字功能 (目前只支持win…...
破解反爬虫策略 /_guard/auto.js(二)实战
这次我们用上篇文章讲到的方法来真正破解一下反爬虫策略,这两个案例是两个不同的网站,一个用的是 /_guard/auto.js,另一个用的是/_guard/delay_jump.js。经过解析发现这两个网站用的反爬虫策略基本是一模一样,只不过在js混淆和生成…...
同样是人工智能 客户在哪儿AI和GPT等大模型有什么不同
书接上回。为了统一回答朋友们的疑惑,此前的两篇文章,着重讲述了客户在哪儿AI的企业全历史行为数据和企业信息查询平台上的数据的区别,以及客户在哪儿AI的ToB获客服务和AI外呼机器人的获客服务的不同。本期接着讲——客户在哪儿AI VS 大模型&…...
AES Android IOS H5 加密方案
前景: 1、本项目原有功能RSA客户端对敏感信息进行加密 2、本次漏洞说是服务端返回值有敏感信息,需要密文返回 3、最初只跟H5联调成功,后续APP联调失败(H5和APP的需求排期不一致),没关注到通用性 方案: 本次方案不…...
一文了解变阻器和电位器的定义、原理、应用及其对比
变阻器的定义 两端可变电阻器(称为变阻器)利用电阻来调节电流。电阻丝环绕在陶瓷或瓷器等绝缘芯上。当刮水器沿着电阻丝移动时,电路的有效电阻会发生变化。因此,它提供了精确的电流控制。调光器、电机速度控制器和加热元件使用变…...
WPF实现一个带旋转动画的菜单栏
WPF实现一个带旋转动画的菜单栏 一、创建WPF项目及文件1、创建项目2、创建文件夹及文件3、添加引用 二、代码实现2.ControlAttachProperty类 一、创建WPF项目及文件 1、创建项目 打开VS2022,创建一个WPF项目,如下所示 2、创建文件夹及文件 创建资源文件夹&…...
使用Dockerfile构建镜像
目录 1.使用Dockerfile构建tomcat镜像 1.1 通过ARG传参构建不同版本的tomcat 2.缩小镜像的体积大小 2.1 使用较小体积的基础镜像 2.2 多级构建减少体积 1.使用Dockerfile构建tomcat镜像 cd /opt mkdir tomcat cd tomcat/ 上传tomcat所需的依赖包 使用tar xf 解压三个压缩…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...
