【C++】new 和 delete

目录

一 引言

二 new

三 delete

四 new和delete操作自定义类型

五 operator new与operator delete函数

六  new和delete的实现原理

1 内置类型

2 自定义类型

1 new的原理

2 delete的原理

3 new T[N]的原理

4 delete[]的原理

七  定位new表达式(placement-new)

八 细节


一 引言

C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因 此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。

二 new

int main()
{// 动态申请一个int类型的空间int* p1 = new int;// 动态申请一个int类型的空间并初始化为10int* p2 = new int(10);// 动态申请3个int类型的空间int* p3 = new int[3];//多个数据初始化int* p4 = new int[3]{1, 2, 3};return 0;
}

三 delete

int main()
{// 动态申请一个int类型的空间int* p1 = new int;// 动态申请一个int类型的空间并初始化为10int* p2 = new int(10);// 动态申请3个int类型的空间int* p3 = new int[3];//多个数据初始化int* p4 = new int[3]{1, 2, 3};delete p1;delete p2;delete[] p3;delete[] p4;return 0;
}

注意:申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用 new[]和delete[]

注意:匹配起来使用。

四 new和delete操作自定义类型

class A
{
public:A(int a = 0): _a(a){cout << "A():" << this << endl;}~A(){cout << "~A():" << this << endl;}
private:int _a;
};struct ListNode
{int _val;ListNode* _next;ListNode(int val):_val(val), _next(nullptr){}
};int main()
{// new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间还会调用构造函数和析构函数A* p1 = (A*)malloc(sizeof(A));A* p2 = new A(1);free(p1);delete p2;// 内置类型是几乎是一样的A* p3 = (A*)malloc(sizeof(A) * 10);A* p4 = new A[10];free(p3);delete[] p4;//对于创建一个链表节点 我们也不像之前那些麻烦了ListNode* n1 = new ListNode(1);ListNode* n2 = new ListNode(2);ListNode* n3 = new ListNode(3);//多个对象动态内存开辟//方法1A aa1(1);A aa2(1);A aa3(1);A* p5 = new A[3]{ aa1, aa2, aa3 };//方法2A* p6 = new A[3]{ A(2), A(2), A(2) };//方法3 -->隐形类型转换A* p7 = new A[3]{ 3, 3, 3 };return 0;
}

malloc 不方便解决动态申请的自定义类型对象的初始化问题

注意:在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与 free不会

new :  step1--> 申请对象空间  step2-->调用构造函数

delete: step1--> 调用析构函数   step2--> 释放对象空间

五 operator new与operator delete函数

new和delete是用户进行动态内存申请和释放的操作符

operator new 和operator delete是 系统提供的全局函数

new在底层调用operator new全局函数来申请空间

delete在底层通过 operator delete全局函数来释放空间。

class Stack
{
public:Stack(int capacity = 4){cout << "Stack(int capacity = 4)" << endl;_a = new int[capacity];_top = 0;_capacity = capacity;}~Stack(){cout << "~Stack()" << endl;delete[] _a;_a = nullptr;_top = 0;_capacity = 0;}
private:int* _a;int  _top;int  _capacity;
};int main()
{Stack* p1 = new Stack;delete p1;Stack* p2 = (Stack*)operator new(sizeof(Stack));operator delete(p2);// new/delete  new[]/delete[]  malloc/free// 一定要配对使用,否则结果是未定义return 0;
}

operator new 和 operator delete库里面的全局函数,封装了malloc 和 free

new : step1--> 申请对象空间 step2-->调用构造函数

step1 为什么不能用malloc 因为malloc 申请空间返回0 但是面向对象是不能接收返回值的  所以创建了operator new 来处理(抛异常)

而operator delete 纯粹是为了和operator new搭对'

六  new和delete的实现原理

1 内置类型

如果申请的是内置类型的空间,new和malloc,delete和free基本类似,不同的地方是: new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回NULL。

2 自定义类型

1 new的原理

1. 调用operator new函数申请空间

2. 在申请的空间上执行构造函数,完成对象的构造

2 delete的原理

1. 在空间上执行析构函数,完成对象中资源的清理工作

2. 调用operator delete函数释放对象的空间

3 new T[N]的原理

1. 调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请

2. 在申请的空间上执行N次构造函数

4 delete[]的原理

1. 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理

2. 调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间

那我们现在可以解释我们为啥要配对使用

 

七  定位new表达式(placement-new)

定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。

使用格式:

new (place_address) type或者new(place_address) type(initializer - list)

place_address必须是一个指针,initializer - list是类型的初始化列表

使用场景:

定位new表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,所以如

果是自定义类型的对象,需要使用new的定义表达式进行显示调构造函数进行初始化。

class A
{
public:A(int a = 0): _a(a){cout << "A():" << this << endl;}~A(){cout << "~A():" << this << endl;}private:int _a;
};int main()
{// 构造函数自动调用A aa1;// A* p2 = new A(1);A* p1 = (A*)operator new(sizeof(A));// 不能这么显示调用构造函数//p1->A(1);// 但是可以用定位new显示调用构造函数new(p1)A(1);// 析构函数可以显示调用p1->~A();operator delete(p1);return 0;
}

八 细节

malloc/free和new/delete的区别

malloc / free和new / delete的共同点是:都是从堆上申请空间,并且需要用户手动释放。

不同的地方是:

1. malloc和free是函数,new和delete是操作符

2. malloc申请的空间不会初始化,new可以初始化

3. malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可,如果是多个对象,[ ]中指定对象个数即可

4. malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型

5. malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常

6. 申请自定义类型对象时,malloc / free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理

缺了好久没写博客, 主要学校的事情太忙了最近, 本节还是很容易的但是非常重要, 注重理解就好

继续加油!

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

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

相关文章

如何使用Docker搭建青龙面板并结合内网穿透工具发布至公网可访问

文章目录 一、前期准备本教程环境为&#xff1a;Centos7&#xff0c;可以跑Docker的系统都可以使用。本教程使用Docker部署青龙&#xff0c;如何安装Docker详见&#xff1a; 二、安装青龙面板三、映射本地部署的青龙面板至公网四、使用固定公网地址访问本地部署的青龙面板 正文…

期货高低板(期货价格飘升,市场掀起高低潮流)

什么是期货高低板&#xff1f; 期货是由交易所统一交易的标准化合约&#xff0c;商品的价格是通过供求关系来决定的。高低板则是期货交易中的常见现象&#xff0c;它表示了在交易过程中&#xff0c;价格波动超过了可设定的最高或最低价&#xff0c;于是交易系统便会出现高板或…

​Halcon机器视觉软件学习指南

引言 Halcon是由德国MVTec软件公司开发的一款领先的机器视觉软件&#xff0c;广泛应用于工业检测、图像分析、医疗图像处理等领域。对于大学生和初学者而言&#xff0c;学习Halcon不仅能够提升技术层面的能力&#xff0c;还能够增强未来的就业竞争力。本文将为您提供一个系统的…

Git 储藏(stash)用法

储藏的基本用法 保存当前的更改 1、查看储藏 git stash list2、更改保存到一个储藏中&#xff1a; git stash save "info"其中&#xff0c;“info” 是可选的注释信息&#xff0c;可以简要描述这个储藏的内容。 3、恢复之前保存的更改 可以使用下面的命令将之前…

安全狗云原生安全-云甲·云原生容器安全管理系统

随着云计算的快速发展&#xff0c;容器技术逐渐成为主流。然而&#xff0c;随着容器的普及&#xff0c;安全问题也日益突出。为了解决这一问题&#xff0c;安全狗推出了云原生容器安全管理系统——云甲。 云甲是安全狗云原生安全的重要组成部分&#xff0c;它采用了先进的云原生…

Jenkins 构建环境指南

目录 Delete workspace before build starts&#xff08;常用&#xff09; Use secret text(s) or file(s) &#xff08;常用&#xff09; Add timestamps to the Console Output &#xff08;常用&#xff09; Inspect build log for published build scans Terminate a …

什么是“人机协同”机器学习?

“人机协同”&#xff08;HITL&#xff09;是人工智能的一个分支&#xff0c;它同时利用人类智能和机器智能来创建机器学习模型。在传统的“人机协同”方法中&#xff0c;人们会参与一个良性循环&#xff0c;在其中训练、调整和测试特定算法。通常&#xff0c;它的工作方式如下…

vscode开发python环境配置

前言 vscode作为一款好用的轻量级代码编辑器&#xff0c;不仅支持代码调试&#xff0c;而且还有丰富的插件库&#xff0c;可以说是免费好用&#xff0c;对于初学者来说用来写写python是再合适不过了。下面就推荐几款个人觉得还不错的插件&#xff0c;希望可以帮助大家更好地写…

亚信安慧AntDB:支撑中国广电5G业务的数据库之力

自2019年6月获得5G牌照以来&#xff0c;中国广电积极利用700MHz频谱资源&#xff0c;迅速崛起为第四大运营商&#xff0c;标志着其在数字通信领域取得的巨大成就。通过与中国移动紧密合作&#xff0c;共建共享基站已超过400万座&#xff0c;为实现自主运营和差异化竞争提供了坚…

淘宝商品评论:商家了解市场趋势和竞争状况的窗口

淘宝商品评论是消费者对购买商品的反馈和评价&#xff0c;是商家了解市场趋势、消费者需求以及竞争状况的重要窗口。通过对商品评论的深入研究和分析&#xff0c;商家可以获取有价值的市场信息和用户需求&#xff0c;从而调整产品策略、优化营销方案以及制定更具针对性的市场竞…

飞书+ChatGPT搭建智能AI助手,无公网ip实现公网访问飞书聊天界面

飞书ChatGPT搭建智能AI助手&#xff0c;无公网ip实现公网访问飞书聊天界面 前言环境列表1.飞书设置2.克隆feishu-chatgpt项目3.配置config.yaml文件4.运行feishu-chatgpt项目5.安装cpolar内网穿透6.固定公网地址7.机器人权限配置8.创建版本9.创建测试企业10. 机器人测试 前言 …

光模块市场分析与发展趋势预测

光模块是光通信领域的重要组成部分&#xff0c;随着数字经济&#xff0c;大数据&#xff0c;云计算&#xff0c;人工智能等行业的兴起&#xff0c;光模块市场经历了快速发展&#xff0c;逐渐在数据中心、无线回传、电信传输等应用场景中得到广泛应用。本文将基于当前光模块全球…

Android Studio打包有哪些优势

大家好&#xff0c;现在移动应用程序的快速发展&#xff0c;开发者需要一个强大又可靠的开发环境来创建和打包高质量的 Android 应用程序。Android Studio 是一款由 Google 官方开发的 Android 应用程序开发环境&#xff0c;提供了许多的优势和便利&#xff0c;那究竟都有哪些优…

基于51的智能交通信号灯设计

文章目录 概要仿真图程序总结 资料下载地址&#xff1a;基于51的智能交通信号灯设计 概要 可实现东西、南北两个方向的红、黄、绿灯按设定的时间亮灭&#xff0c;用以指引交通通行&#xff0c;以倒计时方向显示时间。红、黄、绿交通灯的变化规律为&#xff1a; 1&#xff09…

ros2/ros 4轮2驱机器人xacro/urdf文件示例代码

这个实验中最重要的是&#xff1a;colcon build 之后要记得source install/setup.bash.否则修改的文件是不会更新的。知道了吧 <robot name"half" xmlns:xacro"http://wiki.ros.org/wiki/xacro"><xacro:property name"PI" value"3…

Django 简单图书管理系统

一、图书需求 1. 书籍book_index.html中有超链接&#xff1a;查看所有的书籍列表book_list.html页面 2. 书籍book_list.html中显示所有的书名&#xff0c;有超链接&#xff1a;查看本书籍详情book_detail.html(通过书籍ID)页面 3. 书籍book_detail.html中书的作者和出版社&…

2023年全球软件开发大会(QCon北京站2023)2月-核心PPT资料下载

一、峰会简介 本次活动聚焦云原生、分布式数据库、现代数据技术栈一系列前沿技术与实践&#xff0c;为技术团队负责人、架构师、开发人员等提供了技术学习与交流的平台。 本次峰会包含&#xff1a;AI基础架构、DevOps流程与实践、ML模型效率与易用性、测试环境治理、大规模集…

Nginx 安装(源码编译安装)

Nginx服务器提供了Windows和Linux版本&#xff0c;本文为Linux环境下Nginx服务器的详细安装步骤。 安装环境&#xff1a; Linux服务器操作系统&#xff1a;CentOs 8.1.1911 Nginx版本&#xff1a;1.21.4&#xff08;Linux&#xff09; 安装步骤&#xff1a; 1、安装GCC、aut…

单片机LCD1602

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、LCD1602是什么&#xff1f;二、LCD1602 原理三、显示一个字符四、如何显示四位数五、参考历程六、封装成一个显示 字符和一个显示任意四位数的函数总结 前言…

缓存:系统设计中至关重要的一环

什么是缓存&#xff1f; 缓存就像是一个超快速的存储区域&#xff0c;保存了计算机或手机经常使用的内容的副本&#xff0c;这样可以在不访问较慢的主存储器的情况下快速获取。 一个现实中的例子可以是&#xff0c;每当我们购买杂货时&#xff0c;通常会倾向于大量购买&#…