当前位置: 首页 > news >正文

C++内存管理(区别C语言)深度对比

欢迎来到我的Blog,点击关注哦💕

前言

前面已经介绍了类和对象,对C++面向对象编程已经有了全面认识,接下来要学习对语言学习比较重要的是对内存的管理。

一、内存的分区

  1. 代码区:存放程序的机器指令,通常是可共享的,并且通常为只读的,以防止程序意外修改自身的代码。
  2. 全局/静态存储区:存放全局变量和静态变量,这些变量在程序的整个生命周期内都存在。
  3. 堆区:用于动态分配内存,程序运行时根据需要通过malloc、calloc、realloc等函数在堆区中分配内存空间。
  4. 栈区:存放函数的局部变量和函数调用的参数,由编译器自动管理,遵循后进先出的原则。
  5. 常量区:存放常量数据,如字符串字面量,这些数据在程序运行期间不可修改。
  6. 代码区:存放程序的二进制代码,是程序执行指令的存储空间。

在这里插入图片描述

二、C语言中的内存管理(参考)

  • malloc函数用于动态分配指定大小的内存空间,并返回指向该内存的指针。如果分配成功,返回非NULL指针;否则返回NULL。
  • calloc函数除了分配内存外,还会将分配的内存初始化为零。
  • realloc函数用于调整已分配内存的大小,可能会移动内存块以适应新的大小要求。
  • free函数用于释放之前通过动态内存分配函数分配的内存空间

三、C++中的内存管理

C++内存分配

不同于C语言,C++有着自己独立动态内存开辟的方法:

​ 主要通过newdelete操作符来实现new操作符用于分配单个对象或数组,而deletedelete[]分别用于释放这些对象或数组所占用的内存.

下面是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; 

注意

  1. 不要使用delete释放非new开辟的空间
  2. 不要使用delete释放同一块空间两次
  3. 如果使用new [ ] 开辟数组进行内存分配,应该使用delete [ ] 来释放
  4. 如果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
new
operatornew
构造函数
delete
析构函数
operatordelete

五、replacement new

在C++中new操作符通常用于在堆上分配内存并调用对象的构造函数。除了常规的new操作符外,C++还提供了operator newplacement new两种替代机制。operator newnew操作符内部使用的函数,可以被重载以提供自定义的内存分配策略。而placement new是一种特殊的new表达式,它允许在已分配的内存上构造对象,而不是分配新的内存。

//用法
new(place_address)type

应用场景:

池化技术:

化技术在C++编程中通常指的是预先分配一定数量的资源(如内存、线程等)并存储在一个“池”中,以便在程序运行时可以快速地从中获取和返回资源,而不是每次都进行昂贵的动态分配和释放操作。

这个就是进行已有空间进行对象实例化

六、C语言和C++内存分配的区别

区别malloc free new delete

  1. mallocfree是函数,而newdelete是操作符
  2. malloc不可以初始化而new可以初始化
  3. malloc进行内存分配的时候是手动计算空间的大小,而new后面跟类型,大小在 [ ]中指定
  4. malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型
  5. malloc申请空间失败是返回NULL,而new申请空间失败是捕获异常
  6. 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间 后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理

void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型
5. malloc申请空间失败是返回NULL,而new申请空间失败是捕获异常
6. 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间 后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理

相关文章:

C++内存管理(区别C语言)深度对比

欢迎来到我的Blog&#xff0c;点击关注哦&#x1f495; 前言 前面已经介绍了类和对象&#xff0c;对C面向对象编程已经有了全面认识&#xff0c;接下来要学习对语言学习比较重要的是对内存的管理。 一、内存的分区 代码区&#xff1a;存放程序的机器指令&#xff0c;通常是可…...

手把手带你写一个精简版 HashMap 的 put 方法

&#x1f446;&#x1f3fb;&#x1f446;&#x1f3fb;&#x1f446;&#x1f3fb;关注博主&#xff0c;让你的代码变得更加优雅。 前言 HashMap 大家工作中遇到的太多了&#xff0c;已经成了必须使用的类了&#xff0c; 在面试的时候 HashMap 基本是必问题&#xff0c;但是…...

【面试题】数据结构:堆排序的排序思想?

堆排序的排序思想&#xff1f; 堆排序是一种高效的排序算法&#xff0c;其基本思想是利用堆这种数据结构来实现排序。堆是一种特殊的完全二叉树&#xff0c;通常用数组来表示。堆排序的基本步骤如下&#xff1a; 1. 构建初始堆&#xff1a; 将待排序的数组转换成一个最大堆&a…...

PyTorch 深度学习实践-循环神经网络基础篇

视频指路 参考博客笔记 参考笔记二 文章目录 上课笔记基于RNNCell实现总代码 基于RNN实现总代码 含嵌入层的RNN网络嵌入层的作用含嵌入层的RNN网络架构总代码 其他RNN扩展基本注意力机制自注意力机制&#xff08;Self-Attention&#xff09;自注意力计算多头注意力机制&#xf…...

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转码&#xff0c;方便json序列化。 其中模型llava为本地ollama运行的模型&#xff0c;如&#xff1a;ollama run llava 还有其它的模型如&#xff1a;llava-phi3&#xff0c;通过phi3微调过的版本。 实际测试下来&#xff0c;发现本地多模型的性能不佳&…...

人工智能算法工程师(中级)课程14-神经网络的优化与设计之拟合问题及优化与代码详解

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能算法工程师(中级)课程14-神经网络的优化与设计之拟合问题及优化与代码详解。在机器学习和深度学习领域&#xff0c;模型的训练目标是找到一组参数&#xff0c;使得模型能够从训练数据中学习到有用的模式&am…...

Java异常抛出与处理方法

在Java编程中,异常处理是一个非常重要的部分。通过正确的异常处理,我们可以提高程序的健壮性和可靠性,避免程序在运行过程中出现意外的崩溃。本文将详细讲述Java异常的抛出与处理方法,并通过示例代码进行说明。 一、Java异常的分类 Java中的异常体系结构可以分为三类: 检…...

兼容性测试主要有什么类型?

兼容性测试的类型 有两种类型的兼容性测试。这是一个快速细分。 1、前向兼容性测试 向前兼容性测试或向上兼容性测试可确保当前软件版本在相关组件(例如操作系统、浏览器和第三方库)的未来版本中保持功能。此类测试对于在系统升级期间保持稳定性和用户体验至关重要。 例如&…...

设计模式--组合模式

组合模式&#xff08;Composite Pattern&#xff09;详解 组合模式是一种结构型设计模式&#xff0c;它允许你将对象组合成树形结构来表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 适用场景 需要表示对象的部分-整体层次结构时&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、先学习路由&#xff0c;参考了5.1 2.1、建了一个cloudGatewayDemo&#xff0c;这是用来配置网关的工程&#xff0c;配置如下&#xff1a; http://localhost:18080/aaa/name 该接口代码如…...

数据结构——hash(hashmap源码探究)

hash是什么&#xff1f; hash也称为散列&#xff0c;就是把任意长度的输入&#xff0c;通过散列算法&#xff0c;变成固定长度的输出&#xff0c;这个输出值就是散列值。 举例来说明一下什么是hash&#xff1a; 假设我们要把1~12存入到一个大小是5的hash表中&#xff0c;我们…...

国产麒麟、UOS在线打开pdf加盖印章

PageOffice支持两种电子印章方案&#xff0c;可实现对Word、Excel、PDF文档加盖PageOffice自带印章或ZoomSeal电子印章&#xff08;全方位保护、防篡改、防伪造&#xff09;。Word和Excel的盖章功能请参考&#xff1a;Word和Excel加盖印章和签字功能 &#xff08;目前只支持win…...

破解反爬虫策略 /_guard/auto.js(二)实战

这次我们用上篇文章讲到的方法来真正破解一下反爬虫策略&#xff0c;这两个案例是两个不同的网站&#xff0c;一个用的是 /_guard/auto.js&#xff0c;另一个用的是/_guard/delay_jump.js。经过解析发现这两个网站用的反爬虫策略基本是一模一样&#xff0c;只不过在js混淆和生成…...

同样是人工智能 客户在哪儿AI和GPT等大模型有什么不同

书接上回。为了统一回答朋友们的疑惑&#xff0c;此前的两篇文章&#xff0c;着重讲述了客户在哪儿AI的企业全历史行为数据和企业信息查询平台上的数据的区别&#xff0c;以及客户在哪儿AI的ToB获客服务和AI外呼机器人的获客服务的不同。本期接着讲——客户在哪儿AI VS 大模型&…...

AES Android IOS H5 加密方案

前景&#xff1a; 1、本项目原有功能RSA客户端对敏感信息进行加密 2、本次漏洞说是服务端返回值有敏感信息&#xff0c;需要密文返回 3、最初只跟H5联调成功&#xff0c;后续APP联调失败(H5和APP的需求排期不一致)&#xff0c;没关注到通用性 方案&#xff1a; 本次方案不…...

一文了解变阻器和电位器的定义、原理、应用及其对比

变阻器的定义 两端可变电阻器&#xff08;称为变阻器&#xff09;利用电阻来调节电流。电阻丝环绕在陶瓷或瓷器等绝缘芯上。当刮水器沿着电阻丝移动时&#xff0c;电路的有效电阻会发生变化。因此&#xff0c;它提供了精确的电流控制。调光器、电机速度控制器和加热元件使用变…...

WPF实现一个带旋转动画的菜单栏

WPF实现一个带旋转动画的菜单栏 一、创建WPF项目及文件1、创建项目2、创建文件夹及文件3、添加引用 二、代码实现2.ControlAttachProperty类 一、创建WPF项目及文件 1、创建项目 打开VS2022,创建一个WPF项目&#xff0c;如下所示 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 解压三个压缩…...

概率论原理精解【3】

文章目录 向量值向量值函数导数对称矩阵定义性质例子应用 向量值理论基础定义性质应用示例 向量值函数的导数定义性质应用 向量值 向量值函数导数 D n ⊂ R n , 向量值函数 f : D n → R m D^n \subset R^n,向量值函数f:D^n\rightarrow R^m Dn⊂Rn,向量值函数f:Dn→Rm 1. 向量…...

[C/C++入门][循环]14、计算2的幂(2的n次方)

计算2的幂&#xff08;即2的n次方&#xff09;非常经典。你懂几种方法呢&#xff1f;很多人只会一种&#xff0c;我们来分析一下。 可以通过多种方式实现&#xff1a; 1、最简单的方法之一是使用位运算符<<&#xff0c;它本质上是在二进制表示下对2进行左移操作&#x…...

RPC与服务的注册发现

文章目录 1. 什么是远程过程调用(RPC)?2. RPC的流程3. RPC实践4. RPC与REST的区别4.1 RPC与REST的相似之处4.2 RPC与REST的架构原则4.3 RPC与REST的主要区别 5. RPC与服务发现5.1 以zookeeper为服务注册中心5.2 以etcd为服务注册中心 6. 小结参考 1. 什么是远程过程调用(RPC)?…...

3112. 访问消失节点的最少时间 Medium

给你一个二维数组 edges 表示一个 n 个点的无向图&#xff0c;其中 edges[i] [ui, vi, lengthi] 表示节点 ui 和节点 vi 之间有一条需要 lengthi 单位时间通过的无向边。 同时给你一个数组 disappear &#xff0c;其中 disappear[i] 表示节点 i 从图中消失的时间点&#xff0…...

FastAPI 学习之路(五十二)WebSockets(八)接受/发送json格式消息

前面我们发送的大多数都是text类型的消息&#xff0c;对于text消息来说&#xff0c;后端处理出来要麻烦的多&#xff0c;那么我们可以不可以传递json格式的数据&#xff0c;对于前后端来说都比较友好&#xff0c;答案是肯定的&#xff0c;我们需要做下处理。 首先&#xff0c;…...

Go语言并发编程-案例_3

案例 并发目录大小统计 业务逻辑 统计目录的文件数量和大小&#xff08;或其他信息&#xff09;。示例输出&#xff1a; // 某个目录&#xff1a;2637 files 1149.87 MB 实现思路 给定一个或多个目录&#xff0c;并发的统计每个目录的size&#xff0c;最后累加到一起。 当…...

pikachu之跨站脚本攻击(x‘s‘s)

1get型 输入a看一下 接着输入<a> 发现<>没有被过滤当做标签处理了 尝试在表单提交的框里面&#xff0c;输入xss语句 尝试输入<script>alert(1)</script> 发现有长度限制 因为这里是get请求 get请求的特点是&#xff1a;传参是在url中的 所以我们可以在…...

Qt模型/视图架构——委托(delegate)

一、为什么需要委托 模型&#xff08;model&#xff09;用来数据存储&#xff0c;视图&#xff08;view&#xff09;用来展示数据。因此&#xff0c;模型/视图架构是一种将数据存储和界面展示分离的编程方法。具体如下图所示&#xff1a; 由图可知&#xff0c;模型向视图提供数…...

python3.11SSL: SSLV3_ALERT_HANDSHAKE_FAILURE

参考&#xff1a;python request包 版本不兼容 报错sslv3 alert handshake failure 解决方法-CSDN博客 修改&#xff1a;Python311\Lib\site-packages\urllib3\util\ssl_.py 新版本3.11里默认没有DEFAULT_CIPHERS 补回来: #__imported from 3.6.8 # A secure default. # So…...

[深度学习]基于yolov10+streamlit目标检测演示系统设计

YOLOv10结合Streamlit构建的目标检测系统&#xff0c;不仅极大地增强了实时目标识别的能力&#xff0c;还通过其直观的用户界面实现了对图片、视频乃至摄像头输入的无缝支持。该系统利用YOLOv10的高效检测算法&#xff0c;能够快速准确地识别图像中的多个对象&#xff0c;并标注…...

虎丘网站建设/优化方案怎么写

JPA是什么 Java Persistence API:用于对象持久化的API Java EE 5.0平台标准的ORM规范&#xff0c;使得应用程序以统一的方式访问持久层。 JPA和Hibernate的关系 JPA是Hibernate的一个抽象&#xff08;就像JDBC和JDBC驱动的关系&#xff09;&#xff1a; 1&#xff09;JPA是规范…...

新手做网站遇到的问题以及解决方案/香港百度广告

上节我们学习了容器如何访问外部网络&#xff0c;今天讨论另一个方向&#xff1a;外部网络如何访问到容器&#xff1f; 答案是&#xff1a;端口映射。 docker 可将容器对外提供服务的端口映射到 host 的某个端口&#xff0c;外网通过该端口访问容器。容器启动时通过-p参数映射端…...

58同城网招聘找工作建筑工程/佛山seo外包平台

磁盘阵列df -h看文件系统使用率 : format看可用磁盘 : cfgadm -al看总线连接...

网站设置二级域名好吗/网络黄页推广软件哪个好

一、 文章概述 互联网时代&#xff0c;网络上的数据量每天都在以惊人的速度增长。同时&#xff0c;各类网络安全问题层出不穷。在信息安全重要性日益凸显的今天&#xff0c;作为一名开发者&#xff0c;需要加强对安全的认识&#xff0c;并通过技术手段增强服务的安全性。crypto…...

怎么做点击图片进网站/注册域名在哪里注册

一、OSPF的基本概念和工作过程 1、OSPF路由协议概述 自治系统&#xff08;AS&#xff09;&#xff0c;划分自治系统的原因&#xff1a;收敛时间 内部网关协议(IGP)——RIP、OSPF 外部网关协议&#xff08;EGP&#xff09;——BGP OSPF工作过程&#xff1a; 建立邻接关系—…...

日本配色的网站推荐/网络服务商在哪咨询

如何将idea项目转到 Linux中&#xff1a; 1.在idea中将项目打包成war包&#xff1a; 点击右侧maven&#xff0c;点击clean&#xff0c;清除缓存&#xff1b; 点击package&#xff0c;开始打包成war包。 2.在target目录中找到打包好的war包。 3.通过传输软件将war包文件传到L…...