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 解压三个压缩…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
