「C++」内存管理

🎇个人主页:Ice_Sugar_7
🎇所属专栏:C++启航
🎇欢迎点赞收藏加关注哦!

文章目录

  • 🍉内存分布
  • 🍉关键字new
  • 🍉关键字delete
  • 🍉new和delete的封装实现
  • 🍉总结
  • 🍉写在最后

🍉内存分布

C语言阶段我们知道程序内存主要分为五个区域:栈区、堆区、静态区、代码段和内存映射段

①栈区:存储非静态局部变量、函数参数、返回值等。栈是向下增长的(从高地址低地址增长)
②堆区:用于程序运行时动态内存分配(比如malloc动态开辟空间)。堆可以向上增长(从低地址高地址增长)
③静态区:存储全局数据和静态数据(比如static修饰的变量)。静态区是语法层面的概念,后面学习操作系统的时候我们习惯称它为数据段(操作系统层面的概念)
④代码段:存放可执行的代码只读常量
⑤内存映射段:是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存(Linux部分学习)

它们分布的示意图如下:
在这里插入图片描述


🍉关键字new

class A {
public:private:int _a;
};int main() {A* p = (A*)malloc(sizeof(A));p->_a = 1;return 0;
}

上述代码中p->_a = 1;会报错,因为_a是私有成员也就是说malloc不方便处理动态申请的自定义类型对象的初始化问题
C++中的关键字new则可以有效解决这个问题,来看一下如何使用new

	//内置类型int* p1 = new int;//动态申请1个整型大小的空间int* p2 = new int[5];//动态申请5个整型大小的空间int* p3 = new int(5);//动态申请1个整型大小的空间并初始化为5//自定义类型(假设现在有一个类A)
class A {
public:A(int x) {  //构造函数_a = x;}
private:int _a;
};A aa1(1);A aa2(1);A aa3(1);A* p4 = new A[3]{ aa1, aa2, aa3 };A* p5 = new A[3]{A(2), A(2), A(2) };//匿名对象A* p6 = new A[3]{ 3, 3, 3 };//构造+拷贝构造会被编译器优化为直接构造,即此处直接用3构造对象

通过对比,不难看出malloc只开辟空间
而new会做两件事:①开辟一块空间;②进行初始化。比如对于自定义类型,就会调用它的构造函数(没有构造函数那就会报错)
由此可以看出,new和malloc主要的区别还是在自定义类型的动态内存的开辟上,内置类型除了用法不同,没有区别,只不过new比malloc更方便
此外,malloc申请内存失败会返回空指针,而new则会抛出异常,这更符合面向对象的思想


🍉关键字delete

有开辟就有释放,delete对应C语言的free,但是有所改进,delete除了释放空间,如果是自定义类型,那么还会调用析构函数

	double* p1 = new double;delete p1;double* p2 = new double[10];delete[] p2;//假设有一自定义类型AA* p3 = new A[2];delete[] p3;  //调用2次析构函数

注意:如果申请多个空间,一定要用delete[],不然结果是未定义的,有可能导致程序崩溃


🍉new和delete的封装实现

C++中newdelete都是操作符,它们在使用时分别会调用全局函数operator newoperator delete
如果是new[ ]和delete[ ]则会分别调用operator new[]operator delete[],但是这两个函数最终也是调用operator newoperator delete

operator new实际上是对malloc进行封装,不过有所改进。对于自定义类型的对象,会调用它的构造函数,失败时抛出异常等(其实就是上面所说的new相较于malloc的优势)

operator delete则是对free进行封装

●接着来说下new T[N],它实际是调用operator new函数完成N个对象空间的申请,也就是调用N次构造函数

●同理,delete[]是调用N次析构函数,然后进行free。中括号里面不用写数字的原因是new T[N]和delete[]是配合使用的,delete[]会自动根据N的大小来决定调用多少次析构函数

调用的途径如下:

new->operator new->malloc
delete->operator delete->free

new:先调用operator new申请空间,然后如果是自定义类型,则会调用构造函数
delete:先调用析构函数(自定义类型),然后再调用operator delete释放空间


🍉总结

最后总结一下malloc&free和new&delete的区别(面试题常考)

①malloc和free是函数,new和delete是操作符
②malloc申请的空间不会进行初始化,而new对于自定义类型会调用它的构造函数
③malloc申请空间时,需要我们手动计算所需空间的大小;而new只需写多少个所需类型大小的空间
④malloc返回值类型是void*,接收返回值需要强制类型转换;而new不用
⑤malloc申请空间失败的话,会返回空指针NULL,我们需要判断是否为空;而new不需要,但它需要捕获异常
⑥申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数;而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理


🍉写在最后

以上就是本篇文章的全部内容,如果你觉得本文对你有所帮助的话,那不妨点个小小的赞哦!(比心)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/218721.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小游戏获微信平台扶持,增长爆发点在哪里?开发者还能入局吗?

自2018年正式上线以来,微信小游戏生态的迅速增长,吸引了海量开发者和游戏公司的注意,背靠微信这一平台,小游戏的用户规模也不断膨胀,二者共同作用下,微信小游戏也是爆款频出。 AdSet官网 | 聚合SDK广告变现…

Java 数据结构篇-用数组、堆实现优先级队列

🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 优先级队列说明 2.0 用数组实现优先级队列 3.0 无序数组实现优先级队列 3.1 无序数组实现优先级队列 - 入队列 offer(E value) 3.2 无序数组实现优先级队列 - 出…

山西电力市场日前价格预测【2023-12-14】

日前价格预测 预测说明: 如上图所示,预测明日(2023-12-14)山西电力市场全天平均日前电价为491.16元/MWh。其中,最高日前电价为804.44元/MWh,预计出现在16:15。最低日前电价为336.28元/MWh,预计…

作业11.27

1. 2. def methods(m, n):#创建一个二维数组cp,用于存储到到每个位置的不同走法数量;cp [[0] * n for _ in range(m)]#从第一行和第一列的格子上的走法数量都为1for i in range(m):cp[i][0] 1for j in range(n):cp [0][j] 1#从第二行和第二列开始&…

smartKettle离线部署及问题记录

目录 📚第一章 前言📗背景📗目的📗总体方向 📚第二章 部署📗源码下载📗后端部署📕导入后端项目📕修改settings.xml(自动下载相关jar包)📕 编译📕 …

高精度电压源的作用是什么

高精度电压源是一种用于提供稳定和精确电压输出的电子设备。它们在实验室研究、工业生产和医疗器械等各种应用中发挥着重要作用。下面西安安泰来为大家详细介绍高精度电压源的作用和用途等内容。 一、高精度电压源的作用 提供准确的电压值:高精度电压源可以提供非常…

直流电、交流电、电磁波、光之间的联系

直流电、恒定磁场、交流电、交变磁场、电磁波、光之间的联系 频率为0Hz的直流电及恒定磁场 从频率的角度上看,直流电与恒定磁场的方向不变,频率为0Hz. 如可充电锂离子电池的电压3.7V, 干电池的电压1.5V. 磁铁的磁场方向从N极到S极,始终保持…

AnimateAnything:Fine-grained open domain image animation with motion guidance

1.Introduction 本文旨在借助视频扩散模型的motion prior来解决开放领域图像动画问题,提出了一种可控扩散图像动画方法,能够在保留细节的同时对图像中的任意对象进行动画处理。为了增强用户对动画过程的控制能力,引入了motion area guidance和…

vue3 添加编辑页使用 cron 表达式生成

示例效果图 1、添加组件 <template><div class"v3c"><ul class"v3c-tab"><li class"v3c-tab-item" :class"{ v3c-active: tabActive 1 }" click"onHandleTab(1)">秒</li><li class&qu…

小航助学2023年9月电子学会Scratch三级真题(含题库答题软件账号)

需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09; 单选题2.00分 删除编辑附件图文 答案:C 第1题运行下面程序后&#xff0c;角色的x坐标值是&#xff1f;&#xff08; &#xff09; A、100B、90C、110D、120 答…

【前端学习记录】记一次分片上传逻辑的调试过程

前言 在项目开发的过程中&#xff0c;经常会遇到上传和下载&#xff0c;对于上传来说&#xff0c;如果是小文件的话&#xff0c;接口响应会比较快&#xff0c;但是对于大文件&#xff0c;则需要对其分片以减少请求体的大小和上传时间。 小文件上传 以Vue框架使用<el-uplo…

官宣 鸿雁成为2023汇丰世界羽联世界巡回赛总决赛官方供应商

全屋智能和羽毛球运动能擦出怎样的火花&#xff1f; 鸿雁给你答案&#xff01; 12月13日&#xff0c;2023汇丰世界羽联世界巡回赛总决赛将在杭州举行。 鸿雁签约成为2023汇丰世界羽联世界巡回赛总决赛官方供应商&#xff0c;将携手世界羽联&#xff0c;为广大羽毛球爱好者们…

Yolov5双目测距-双目相机计数及测距教程(附代码)

引言 在计算机视觉领域&#xff0c;Yolov5-Binocular相机距离计数及测距是一个引人注目的研究方向。本教程将为小白用户提供一个简明扼要的学习指南&#xff0c;涵盖了关键步骤&#xff0c;包括标定、公示推倒以及重要的代码片段。 第一步&#xff1a;环境搭建 首先&#x…

【Geoserver】将geoserver迁移到jetty的发行包中

之前讲了在Geosever的二进制发行包中升级jetty的内容&#xff0c;我测试之后发现有些问题&#xff0c;本地运行可能没有问题&#xff0c;但是在linux上运行报错了。 于是我想着换个思路好了&#xff0c;总是想着将Geosever中的jetty包替换掉&#xff0c;干脆反过来&#xff0c;…

2023_Spark_实验二十六:编写Shell模拟生成点击实时数据

引言&#xff1a;流式数据处理主要处理实时数据&#xff0c;由于实验教学过程中&#xff0c;每个同学无法拿到实时数据&#xff0c;因此我们开发shell脚本模拟实时数据生成&#xff0c;支持后续实验。 实验目的&#xff1a;通过开发模拟实时点击流shell脚本&#xff0c;模拟实时…

【Database】什么是数据库?常见的数据库类型有哪些?

什么是数据库&#xff1f;常见的数据库类型有哪些&#xff1f; 首先&#xff0c;什么是数据库&#xff1f;把它想象成一个数字游乐场&#xff0c;我们以结构化的方式组织和存储大量信息。现在&#xff0c;让我们来谈谈数据库的主要类型。 关系型数据库&#xff1a; 想象一下…

深度学习的目标检测算法综述

信息记录材料 2022年10月 第23卷第10期 【摘要】目标检测是深度学习的一个重要应用&#xff0c;目前在智能驾驶、工业检测相关领域都获得应用&#xff0c;具有重要的现实意义。本文对基于深度学习目标检测算法原理和应用情况进行简述&#xff0c;首先介绍结合区域提取和卷积神经…

Spring上IOC之@EnableAspectJAutoProxy

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

3分钟,掌握“曲面屏显示屏”

在3分钟内掌握“曲面屏显示屏”的概念和特点&#xff0c;可以按照以下步骤进行&#xff1a; 一、了解曲面屏显示屏的基本概念 曲面屏显示屏是一种采用柔性塑料的显示屏&#xff0c;主要通过OLED面板来实现。相比直面屏幕&#xff0c;曲面屏幕弹性更好&#xff0c;不易破碎。此外…

扫描电镜(SEM)样品在进行扫描电镜观察前需要进行哪些处理

对于扫描电镜&#xff08;Scanning Electron Microscope&#xff0c;SEM&#xff09;样品的制备&#xff0c;需要经过一系列处理步骤以确保样品表面的干净、导电性好&#xff0c;并且能够提供高质量的显微图像。以下是一些常见的处理步骤&#xff1a; 1. 固定样品&#xff08;…