「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;

	//假设有一自定义类型A
	A* 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在释放空间前会调用析构函数完成空间中资源的清理


🍉写在最后

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

牛客——不重复数字(哈希表、平衡树)

今天的第二题。下面这道题呢有两种解法,一种基于哈希表,一种基于平衡树。 登录—专业IT笔试面试备考平台_牛客网 题目描述 给出N个数,要求把其中重复的去掉,只保留第一次出现的数。 例如,给出的数为1 2 18 3 3 …

接口测试要测试什么?怎么测?

本文主要分为两个部分: 第一部分:主要从问题出发,引入接口测试的相关内容并与前端测试进行简单对比,总结两者之前的区别与联系 第二部分:主要介绍为什么要做接口测试,并简单总结接口持续集成和接口质量评估…

Java调用百度翻译API和调用有道翻译API进行翻译

目录 界面编写 调用百度API 调用有道API 源代码 界面编写 我们首先需要设计出这个翻译程序的GUI界面,我们写一个类继承自JFrame类,用来展示程序的主窗口,设置好窗口的名称和大小,设置在关闭窗口时终止程序,为了界…

React Native:入门知识了解

什么是React Native React Native(简称RN)是Facebook于2015年4月开源的跨平台移动应用开发框架,是Facebook早先开源的JS框架 React 在原生移动应用平台的衍生产物,目前支持iOS和安卓两大平台。React Native使用Javascript语言&am…

功能更新|免费敏捷工具Leangoo领歌私有部署新增第三方身份认证和API对接

Leangoo领歌是一款永久免费的专业的敏捷开发管理工具,提供端到端敏捷研发管理解决方案,涵盖敏捷需求管理、任务协同、进展跟踪、统计度量等。 Leangoo支持敏捷研发管理全流程,包括小型团队敏捷开发,规模化敏捷SAFe,Scr…

windows数据备份方法

信息时代数据已成为个人及企业的重要资产,数据丢失或者损坏会带来无法弥补的损失。数据安全主要关注两个方面数据容灾和数据备份。容灾的目的是防止硬件发生错误,通过多个相同或类似硬件避免单一硬件故障造成的数据丢失。数据备份除了可以防止单一硬件错…

使用QT基于YMODEM协议实现串口文件发送(和xshell互通)

背景 项目需要用QT实现一个YMODEM文件传输的功能,目标下位机是MCU嵌入式设备,且下位机程序已经经过xshell传输文件的验证。 YMODEM 简介 YMODEM协议是一个文件传输协议,常用于嵌入式设备。本文不对YMODEM做过多的阐述,阅读需建…

Tomcat主配置文件(server.xml)详解

前言 Tomcat主配置文件(server.xml)是Tomcat服务器的主要配置文件,文件位置在conf目录下,它包含了Tomcat的全局配置信息,包括监听端口、虚拟主机、安全配置、连接器等。 目录 1 server.xml组件类别 2 组件介绍 3 se…

003 FeedForward前馈层

一、环境 本文使用环境为: Windows10Python 3.9.17torch 1.13.1cu117torchvision 0.14.1cu117 二、前馈层原理 Transformer模型中的前馈层(Feed Forward Layer)是其关键组件之一,对于模型的性能起着重要作用。下面将用900字对…

cpp:1:10: fatal error: opencv2/core.hpp: 没有那个文件或目录

前言&#xff1a; 我按照官网方法安装了opencv&#xff0c;运行的也是官网的测试代码&#xff1a; #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> using namespace cv; int main() {printf("hello world")return 0; }

boost1.55 安装使用教程 windows

第一步 &#xff1a;首先在boost官网上下载库压缩包 添加链接描述 选择自己需要的版本进行下载 解压后执行booststrap.bat 用来生成创建b2.exe 和bjam.exe 拓展&#xff1a;.\b2 --help 了解一下有哪些参数可以配置 默认b2.exe编译后&#xff0c;链接到项目如果出现如下错误…

VLAN基本原理

目录 一、VLAN概念及优势 &#xff08;一&#xff09;基本理念 &#xff08;二&#xff09;VLAN的特点 二、VLAN ID 种类、范围及用途 &#xff08;一&#xff09;静态VLAN &#xff08;二&#xff09;动态VLAN &#xff08;三&#xff09;VLAN三种端口类型 &#xff0…

深入理解Java虚拟机---类加载机制

类加载机制 什么是类加载机制类加载的时机类加载的过程加载验证文件格式验证元数据验证字节码验证符号引用验证 准备解析初始化 类加载器双亲委派模型 什么是类加载机制 虚拟机把描述类的数据从 Class 文件加载到内存&#xff0c;并对数据进行校验、转换解析和初始化&#xff…

centOS安装bochsXshell连接centos启动可视化界面

centOS安装bochs 参考&#xff1a;https://blog.csdn.net/muzi_since/article/details/102559187 首先安装依赖环境&#xff1a; yum install gtk2 gtk2-devel yum install libXt libXt-devel yum install libXpm libXpm-devel yum install SDL SDL-devel yum install libXr…

已解决:No goals have been specified for this build. You must specify a vali

[ERROR] No goals have been specified for this build. You must specify a valiTOC 完整报错 No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format : or :[:]:. Available lifecycle phases are: pre-clean, c…

6. Service详解

6. Service详解 文章目录 6. Service详解6.1 Service介绍6.2 Service类型6.3 Service使用6.3.1 实验环境准备6.3.2 ClusterIP类型的Service6.3.3 HeadLess类型的Service6.3.3.1 deployment和statefulset区别6.3.3.2 statefulset deployment 区别 6.3.4 NodePort类型的Service6.…

Trace 在多线程异步体系下传递

JAVA 线程异步常见的实现方式有&#xff1a; new ThreadExecutorService 当然还有其他的&#xff0c;比如fork-join&#xff0c;这些下文会有提及&#xff0c;下面主要针对这两种场景结合 DDTrace 和 Springboot 下进行实践。 引入 DDTrace sdk <properties><java.…

湖农大邀请赛shell_rce漏洞复现

湖农大邀请赛 shell_rce 复现 在 2023 年湖南农业大学邀请赛的线上初赛中&#xff0c;有一道 shell_rce 题&#xff0c;本文将复现该题。 题目内容&#xff0c;打开即是代码&#xff1a; <?phpclass shell{public $exp;public function __destruct(){$str preg_replace…

Shopify怎么避免被封店?封店原因有哪些?

市场研究的一份报告显示&#xff0c;全球跨境电子商务市场预计到2028年将达到30422亿美元&#xff0c;其中&#xff0c;亚太地区是最大的跨境电商市场&#xff0c;据海关统计数据&#xff0c;近五年来&#xff0c;我国跨境电商进出口增长近10倍。跨境电商业务新的增长风口已经到…

图像去噪——PMRID训练自己数据集及推理测试(详细图文教程)

目录 一、源码包准备二、数据集准备2.1 提取数据集名称2.2 .txt报错问题2.2.1 正确格式2.2.2 错误格式 三、修改配置参数四、训练及保存模型权重4.1 训练4.2 保存模型权重文件 五、模型推理测试5.1 导入测试集5.2 测试5.3 测试结果5.3.1 测试场景15.3.2 测试场景2 5.4 推理速度…