【C++】new和delete深度解析

在这里插入图片描述


new/delete测试环境:visual studio2019社区版


一、new/delete是什么?

在C++编程中,new 和 delete 是用于动态分配和释放内存的操作符,简单来讲c++申请空间和释放空间的最好办法就是:new 和 delete,由于是操作符,所以使用new 和 delete不需要包头文件。

1.new

new:new 操作符用于动态分配内存来创建一个对象或一块内存区域,并返回一个指向分配内存的指针。它用于在堆上分配内存,以便在程序的任何地方使用,而不仅仅在栈上。通常用于创建动态对象,如类实例。

例如,创建一个整数对象并分配内存可以这样做:

int* myInt = new int;

这将在堆上分配一个整数大小的内存块,并返回一个指向该内存的指针。

2.delete

delete:delete 操作符用于释放先前由 new 分配的内存,以防止内存泄漏。它删除之前分配的内存,并将指针置为空,以防止访问已释放的内存。

例如,删除之前分配的整数对象内存可以这样做:

delete myInt;
myInt = nullptr; // 将指针置为空,以避免野指针

注意:在使用 new 分配内存后,务必使用 delete 来释放内存,以避免内存泄漏。否则,分配的内存将一直保留在堆上,直到程序终止,这可能导致内存资源耗尽。最好的做法是使用智能指针。

二、new/delete怎么用?

1.new

new会在堆上申请一片空间,并且会返回这片空间的地址,所以要用指针类型接收,如果申请空间失败,new会抛出异常值

 模板:Type* T=new Type

为内置类型申请空间:

int* mytype = new int

new内置类型注意:

1.new不会对内置类型申请的空间初始化,用户需要自己初始化。
2.new内置类型是在堆上申请空间,系统不会自己释放空间,所以需要用户使用delete手动释放空间。

为自定义类型申请空间

class A
{
public:
	A(int a=1)
	{
		_a=a;
	}
private:
	int _a;
}//new
	A* p1 = new A;

new自定义类型注意:

1.new会对自定义类型申请的空间进行特殊处理,在new的过程中会调用自定义类型的构造函数。
2.new自定义类型是在堆上申请空间,系统不会自己释放空间,所以需要用户使用delete手动释放空间。

ps:查看new调用自定义类型构造的现象
在这里插入图片描述

2.delete

和new配套使用,释放new从堆上开辟的空间

//Type* T=new Type
模板:delete T;

*为内置类型释放空间

//int* mytype = new int;
delete mytype;

delete内置类型注意:

1.此时的delete行为和free()一致,单纯释放new开的空间。此时讲deletet替换成free也不会有问题

为自定义类型释放空间

class A
{
public:
	A(int a=1)
	{
		_a=a;
	}
private:
	int _a;
};

	A* p1 = new A;
	//delete
	delete p1;

delete内置类型注意:

1.此时的delete不仅仅会释放new的空间,还会调用自定义类型的析构函数,先后过程为先调用析构函数,再释放空间
ps delete调用自定义类型析构的现象
在这里插入图片描述

3.new[]

c++申请多个连续对象使用new[],其中[]中可指定申请对象的个数,如果申请失败,则会抛出异常值。

模板:Type* T = new Type[n];//申请n个对象的Type数组

为内置类型申请空间

int* mytype = new int[10];

new[]内置类型注意:

1.new不会对内置类型申请的空间初始化,用户需要自己初始化。
2.new内置类型是在堆上申请空间,系统不会自己释放空间,所以需要用户使用delete[]手动释放空间。

ps:可在定义时同时初始化,
在这里插入图片描述
为自定义类型申请空间

class A
{
public:
	A(int a=1)
	{
		_a=a;
	}
private:
	int _a;
};

	A* p1 = new A[2]{01};

new[]自定义类型注意:

1.new[n]会对自定义类型申请的空间进行特殊处理,在new的过程中会调用n次自定义类型的构造函数。
2.new[]自定义类型是在堆上申请空间,系统不会自己释放空间,所以需要用户使用[]delete手动释放空间。

ps:new[n]调用构造函数现象
在这里插入图片描述

4.[]delete

delete[]功能为释放由new[]申请的连续空间。

为内置类型释放空间

int* mytype = new int[10];
delete []mytype;

[]delete释放内置类型空间注意:

1.不需要在[]delete的[]中指定对象个数
2.[]delete务必和new[]配套使用否则容易出现未定义的错误

为自定义类型释放空间

A* p1 = new A[2]{01};
delete []p1;

[]delete释放自定义类型空间注意:

1.不需要在[]delete的[]中指定对象个数
2.[]delete务必和new[]配套使用否则容易出现未定义的错误
3.在使用[]delete中会调用对象的析构函数,再释放空间,先后是:先调用析构再释放空间

ps:[]delete调用析构函数的现象
在这里插入图片描述


三、new/delete为什么?

1.为什么有operator new/operator delete?

在前面的汇编代码中我们发现new和delete都会调用operator new/operator delete
(在vs2019中delete对operator delete调用隐藏了起来),那么这是为什么呢?

在这里插入图片描述

在C++中,operator new和operator delete是用于动态内存管理的特殊函数,这两个函数不是重载函数,是c++开发者定义的两个特殊的全局函数。它们允许程序员自定义内存分配和释放的行为,以满足特定的需求。这两个操作符通常与关键字new和delete一起使用,在汇编过程中new和delete都会调用operator new/operator delete来实现开辟空间和释放空间。

实际上operator new和operator delete这两个函数的底层还是用c中用来申请和释放空间的函数“malloc”和f“ree()”实现的,operator new和operator delete是“malloc”和“free”的高级封装版本,完善了对错误的处理。c++创造operator new和operator delete是为了更好的为c++"面向对象“的概念服务,因为“malloc”和“free”对异常的处理不适合c++理念,一句话讲,就是c中原始的“malloc”和“free”不好用,c++把它们封装成了operator new和operator delete.
在这里插入图片描述


2.为什么要匹配使用new和delete?

为什么需要区分使用new和delete,new[]和delete[]?

1.正确的内存释放: 使用new和delete,new[]和delete[]的配对使用是为了确保正确的内存释放。数组对象通常需要更复杂的析构和释放过程,因此需要使用new[]和delete[]。
2.调用正确的析构函数: 使用new[]分配数组时,C++会在每个数组元素上调用构造函数,而使用delete[]释放数组时,会在每个数组元素上调用析构函数。这样确保了每个对象的构造和析构过程都被正确执行。
3.避免未定义行为: 使用new[]和delete[]配对使用可以避免因未定义的内存释放行为而引起的问题。在释放数组时,系统需要知道数组的大小,以便逐个调用对象的析构函数。

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

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

相关文章

力扣21:合并两个有序链表

力扣21:合并两个有序链表 **题目描述:**将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1: 输入:l1 [1,2,4], l2 [1,3,4] 输出:[1,1,2,3,4,4] 示例 2&…

超级APP,All in one APP

在信息化时代,企业需要处理的数据和使用的各种系统繁多复杂。然而,传统的应用往往孤立存在,导致数据无法流动和系统无法高效对接。WorkPlus作为一款超级APP,以其全面的功能和强大的集成能力,实现了数据到系统的全方位集…

高压MOS/低压MOS在单相离线式不间断电源上的应用-REASUNOS瑞森半导体

一、前言 单相离线式不间断电源只是备援性质的UPS,市电直接供电给用电设备再为电池充电,一旦市电供电品质不稳或停电时,市电的回路会自动切断,电池的直流电会被转换成交流电接手供电的任务,直到市电恢复正常。UPS只有…

Jmeter工具二次开发

一、JMeter 二次开发方向 1、函数开发,主要为JMeter 函数库 2、插件开发,一般主要做取样器开发 3、基于执行引擎开发,有效解决单独开发的测试平台或工具中,底层执行引擎开发相对复杂、周期长的问题,利用 JMeter 执行…

Redis为什么要使用SDS作为基本数据结构

Redis为什么要使用SDS作为基本数据结构 Redis SDS与C语言中字符串的对比二进制安全兼容部分C字符串函数 Redis SDS与C语言中字符串的对比 SDS中保存了字符串的长度属性,我们在获取字符串长度是的时间复杂度为O(1),而C中字符串则需要对字符串进行遍历时间…

linux 不同用户不同jdk

0、 解压一个新版本的jdk 1、 检查root用户下的环境变量,是否配置了JAVA_HOME,基于这个变量再配置的PATH变量是实现切换的前提。 2、 创建新用户 adduser jdk11 passwd jfjfjfjfjfjfj123 3、 编辑改用下的 .bashrc 文件 执行命令进行编辑&#xff0…

倍福CX9020 Windows CE6.0安装中文字库方法(附字库文件)

应用背景介绍 倍福的EPC产品有些是附带Windows CE系统的,例如CX9020,而且多数系统都是英文的,而且没有附带中文的字库,如果想要在PLC HMI中使用中文进行显示就无法实现,经常有工程师在电脑上编好程序和界面以后测试没…

使用Navicat导出ER图详细教程

文章目录 打开Navicat,点击模型点击新建模型选择物理模型点击文件,选择从数据库导入选择要导入的数据库点击文件,选择导出的格式成品 打开Navicat,点击模型 点击新建模型 选择物理模型 点击文件,选择从数据库导入 选择…

C++动态库

C动态库 动态库文件(Dynamic Link Library,DLL)是程序在运行时所需要调用的库。静态库文件是程序在编译时所需要调用的库。 1 环境介绍 VS版本:VS2017 编程语言:C 2 功能介绍 使用VS2017项目模板创建C动态库生成…

Java程序设计实验5 | Java API应用

*本文是博主对Java各种实验的再整理与详解,除了代码部分和解析部分,一些题目还增加了拓展部分(⭐)。拓展部分不是实验报告中原有的内容,而是博主本人自己的补充,以方便大家额外学习、参考。 (解…

CSS3 2D、3D转换

一、CSS3 2D转换&#xff1a; CSS3转换可以对元素进行移动、缩放、转动、拉长或拉伸。 2D变换的方法&#xff1a;translate()、rolate()、scale()、skew()、matrix()。 <style> div { width:200px; height:100px; background-color:red; /* Rotate div */ tran…

混淆矩阵和相应参数详解

如果一个模型在能够尽量捕获少数类的情况下&#xff0c;还能够尽量对多数类判断正确&#xff0c;则这个模型就非常优秀了。为了评估这样的能力&#xff0c;我们将引入新的模型评估指标&#xff1a;混淆矩阵和ROC曲线。 上面是混淆矩阵。接下来我们结合图像解释一下准确率&#…

AMESim 2021安装教程

主要是AMESim的安装 写在前面&#xff0c;由于项目需要&#xff0c;需要自学AMESim&#xff0c;因此需要安装这个软件&#xff0c;目前仅仅安装使用&#xff0c;还不涉及到与MATLAB的联合仿真&#xff0c;老板说用 RT LAB半实物仿真平台&#xff0c;但是简单搜了一下&#xff0…

阻塞队列和定时器的使用

阻塞队列 谈到队列,大家就能想到队列的先进先出原则,但有些特殊的队列,虽然也是先进先出的,但是带有阻塞功能,我们把这种队列叫做阻塞队列. ★如果队列为空,执行出队操作就会阻塞,阻塞到另外一个线程往队列里添加元素(队列不为空)为止. ★如果队列满了,执行入队操作时,也会阻…

“GUI图形化界面的魅力、SSH协议的安全通信与IDEA集成Git的高效开发“

文章目录 引言一、GUI图形化界面的实际应用二、SSH协议的安全通信什么是SSH?git/github生成密钥并通过远程github仓库配置 三、IDEA集成Git的快速上手指南总结 引言 在计算机科学领域&#xff0c;图形用户界面&#xff08;GUI&#xff09;是一种以图形方式呈现信息和交互的用…

Flutter笔记:绘图示例 - 一个简单的(Canvas )时钟应用

Flutter笔记 绘图示例 - 一个简单的&#xff08;Canvas &#xff09;时钟应用 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_2855…

大数据毕业设计选题推荐-污水处理大数据平台-Hadoop-Spark-Hive

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

【数据结构】Lambda

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;浅谈数据结构 &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; Lambda表达式 1. 背景1.1 语法1.2 函…

【C++优先队列使用】问题总结

说明&#xff1a; 文章内容为关于priority_queue的使用总结&#xff0c;在C中要包含头文件<queue>文章内容为个人的学习整理&#xff0c;如有错误&#xff0c;欢迎指正。 文章目录 1. 优先队列默认是大根堆2. 关于优先队列和sort的比较逻辑2.1 sort的比较逻辑2.2 优先队…

python操作链接数据库和Mysql中的事务在python的处理

python操作数据库 pymysql模块: pip install pymysql作用:可以实现使用python程序链接mysql数据库&#xff0c;且可以直接在python中执行sql语句 添加操作 import pymysql #1.创建链接对象c conn pymysql.Connect(host127.0.0.1,#数据库服务器主机地址port3306, #mysql的端口…
最新文章