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 解压三个压缩…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...