C++初阶语法——new,delete开辟/销毁动态内存空间

前言:在C语言中,有malloc,realloc,calloc开辟动态内存空间,free销毁动态内存空间。而在C++中,使用new开辟动态内存空间,delete销毁动态内存空间。不仅简化了操作,更为重要的是,解决自定义类型的初始化问题

目录

  • 一.简化操作
  • 二.解决自定义类型初始化问题(重点)
  • 三.new不检查失败,抛异常
    • 1.抛异常
    • 2.捕获异常(try catch)
  • 四.operator new/operator delete函数
    • 1.内置类型
    • 2.自定义类型

一.简化操作

用法:new 类型 delete 指针
创建数组:new 类型[数据个数] delete[] 指针
编译器会自动计算类型大小,并且不用再强制转换类型。大大简化了操作,但是要记住下面这三句话:一定要匹配使用!匹配使用!匹配使用!

	//int* a = (int*)malloc(sizeof(int));//free(a);int* a = new int;delete a;int* b = new int[10];delete[] a;

二.解决自定义类型初始化问题(重点)

new/delete 和malloc/free最大的区别就是new/delete对于自定义类型除了开空间以外会去调用它们的构造函数/析构函数
new会调用构造函数,delete会调用析构函数。

以栈类为例:

typedef int DataType;
class Stack {
public:Stack(int capacity = 4)//构造函数 {_arr = new DataType[capacity];_capacity = capacity;_size = 0;}void StackPush(DataType Data){_arr[_size] = Data;_size++;}~Stack() //析构函数{delete[] _arr;_capacity = _size = 0;}
private:DataType* _arr;int _capacity;int _size;
};
int main()
{Stack* ptr = (Stack*)malloc(sizeof(Stack)); //malloc开辟一个自定义的栈对象ptr->StackPush(1); //压栈free(ptr);return 0;
}

控制台显示如下:我们知道不为0代表着程序出错,那上面代码为什么出错呢?这就是我们强调的malloc只是单纯的开辟空间,不会去调用自定义类型Stack的构造函数,也就没有初始化,没有初始化还向里面压栈肯定会出现错误的。
在这里插入图片描述

改成new和delete则不会报错:

int main()
{Stack* ptr = new Stack;ptr->StackPush(1);delete ptr;//free(ptr)  不行,free不会去调用析构函数,资源得不到清理。return 0;
}

三.new不检查失败,抛异常

我们用malloc开辟空间时,一般都会写一个if条件语句防止开辟空间失败,而new不再检查失败,出错时会直接抛异常,也就是说用new的话不需要再写if条件防止开辟空间失败。

void Func()
{//mallocint* a = (int*)malloc(sizeof(int)*10);if (a == nullptr) //if判断{return;}free(a);//newint* b = new int[10];delete[] b;
}

1.抛异常

用malloc开辟同样大小的空间并不会提示错误,而new会。
在这里插入图片描述

2.捕获异常(try catch)

利用try和catch捕获异常,找到出现异常的原因。

int main()
{try{char* p2 = new char[0x7fffffff];}catch (const exception& error){cout << error.what() << endl;}

控制台显示如下:
在这里插入图片描述

出现异常后会发生执行流跳跃,不执行异常后的代码:

int main()
{try{cout << "正常" << endl;char* p2 = new char[0x7fffffff];cout << "异常" << endl;}catch (const exception& error){cout << error.what() << endl;}return 0;
}

控制台输出如下:可以看到,输出“异常”的代码并没有被执行。这点类似goto语句,出现异常之后,就直接跳到catch语句。这样的设计避免了出错了还运行后面的语句,防止错上加错。
在这里插入图片描述

四.operator new/operator delete函数

new和delete是用户进行动态内存申请和释放的操作符,operator new和operator delete是系统提供的全局函数,new在地城调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。

operator new是malloc函数的封装,也就是说,new出来的空间实际上是malloc出来的。不同的是,malloc函数出现错误会返回NULL,而C++需要的是出现错误返回异常,因此封装malloc函数,但出现错误返回异常。
operator delete原理与operator类似。

如下:operator new/operator delete使用方法与malloc/free相同。

	int* a = (int*)malloc(sizeof(int) * 10);free(a);int* b = (int*)operator new(sizeof(int) * 10);operator delete(b);

1.内置类型

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

以下三种方式都可以释放空间,实际上都是使用free释放空间。但是第一第二种并不推荐。使用时一定要匹配使用。以避免特殊情况出现。

	int* a = new int[10];//都可以释放申请的空间//free(a);//delete a;delete[] a;

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来释放空间。

文末BB:对哪里有问题的朋友,尽管在评论区留言,若哪里写的有问题,也欢迎朋友们在评论区指出,博主看到后会第一时间确定修改。最后,制作不易,如果对朋友们有帮助的话,希望能给博主点点赞和关注.

在这里插入图片描述

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

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

相关文章

前端面试:【Vuex】Vue.js的状态管理利器

嗨&#xff0c;亲爱的Vuex探险家&#xff01;在Vue.js开发的旅程中&#xff0c;有一个强大的状态管理库&#xff0c;那就是Vuex。Vuex是Vue.js的官方状态管理工具&#xff0c;通过State、Mutation、Action和Module等核心概念&#xff0c;协助你轻松管理应用的状态。 1. 什么是V…

基于Java SpringBoot+vue+html 的地方美食系统(2.0版本)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W,csdn、博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 文章目录 1 简介2 技术栈3 系统流程的分析3.1 用户管理的流程3.2个人中心管理流程3.3登录流程 4系统设计…

【第16例】IPD开发流程:横向管理工具之袖珍卡

目录 前言 袖珍卡 作者介绍 相关课程 前言 IPD 本身是一个非常庞杂的体系&#xff0c;几乎涵盖了企业的方方面面。 不仅仅是华为&#xff0c;包括一些引入 IPD 的新星科技企业。 他们对 IPD 的引入也是走了先僵化再优化的一个过程。 比如说开始的阶段全盘照抄走流程&…

【Redis从头学-7】Redis中的Set数据类型实战场景之用户画像去重、共同关注、专属粉丝

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;啥技术都喜欢捣鼓捣鼓&#xff0c;喜欢分享技术、经验、生活。 &#x1f60e;人生感悟&#xff1a;尝尽人生百味&#xff0c;方知世间冷暖。 &#x1f4d6;所属专栏&#xff1a;Re…

matlab使用教程(20)—插值基础

1.网格和散点样本数据 插值是在位于一组样本数据点域中的查询位置进行函数值估算的方法。函数值是根据最接近查询点的样本数据点计算的。MATLAB 根据样本数据的结构&#xff0c;可以执行两种插值。样本数据可以形成网格&#xff0c;也可以是分散的。 网格化的样本数据使得插值…

Matlab使用

Matlab使用 界面介绍 新建脚本&#xff1a;实际上就是新建一个新建后缀为.m的文件 新建编辑器&#xff1a;ctrlN 打开&#xff1a;打开最近文件&#xff0c;以找到最近写过的文件 点击路径&#xff0c;切换当前文件夹 预设&#xff1a;定制习惯用的界面 常见简单指令 ;…

十亿次实验,用概率解读周易大衍筮法的奥秘

还记得封神电影里的文王占卜吗&#xff1f; 也就是著名的大衍筮法。 《易传》曰&#xff1a;大衍之数五十&#xff0c;其用四十有九。分而为二以象两&#xff0c;挂一以象三&#xff0c; 揲之以四以象四时&#xff0c;归奇于扐以象闰&#xff0c;五岁再闰&#xff0c;故再扐而…

解决云服务连接时长过短,不到一会儿自动断开

我们在使用xshell或者FinalShell连接云服务器操作时&#xff0c;总是十分钟就自动断开&#xff0c;很烦&#xff0c; 下面我们设置一下&#xff0c;让他可以使用很长时间&#xff08;需要有一定的linux命令的基础&#xff09; cd /etc/ssh 进入到ssh这个目录&#xff0c;查看…

C++ OpenSSL 3.0.8 AES加解密

2023年后&#xff0c;openssl进入3.0版本&#xff0c;openssl的加解密代码也出现了一些变化&#xff0c;例如编译时会有如下错误&#xff1a; error C4996: ‘AES_set_encrypt_key’: Since OpenSSL 3.0 如果使用OpenSSL 1.1.1 sdk编译则没有上述错误&#xff0c;使用3.0以上的…

k8s ingress

一、浅谈ingress &#xff08;ingress 是与service配合使用的&#xff09; Ingress能把Service&#xff08;Kubernetes的服务&#xff09;配置成外网能够访问的URL&#xff0c;流量负载均衡&#xff0c;及SSL&#xff0c;并提供域名访问的虚拟主机等&#xff0c;客户通过访问UR…

使用Python实现微信自动回复,操作简单,小白也会使用!秒回女朋友消息 泰裤辣!

一、安装itchat库 首先,我们需要安装itchat库,它是一个用于微信个人号的微信Python API,可以用于实现微信自动回复、微信消息的获取、微信好友的管理等功能。 可以使用以下命令安装itchat库: pip install itchat二、登录微信 在代码中,我们需要使用itchat库登录微信账…

【C++11算法】iota算法

文章目录 前言一、iota函数1.1 iota是什么&#xff1f;1.2 函数原型1.3 参数和返回值1.4 示例代码1.5 示例代码21.6 示例代码3 总结 前言 C标准库提供了丰富的算法&#xff0c;其中之一就是iota算法。iota算法用于填充一个区间&#xff0c;以递增的方式给每个元素赋予一个值。…

Ubuntu22.4系统mongodb数据库安装

Ubuntu22.4系统mongodb数据库安装 1、打开终端并运行以下命令&#xff0c;以导入 MongoDB GPG 密钥&#xff1a; wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | sudo apt-key add -2、添加 MongoDB 仓库到你的系统。根据你的 Ubuntu 版本&#xff0c;选择…

万界星空科技/免费MES系统/免费质量检测系统

质量管理也是万界星空科技免费MES中的一个重要组成部分&#xff0c;旨在帮助制造企业实现全面的质量管理。该系统涵盖了供应商来料、生产过程、质量检验、数据分析等各个环节&#xff0c;为企业提供了一站式的质量管理解决方案。 1. 实时质量监控 质量管理能够实时监控生产过程…

ardupilot开发 --- Lua脚本篇

概述 ArduPilot引入了对Lua脚本的支持&#xff1b; Lua脚本存放在 SD card 中&#xff1b; Copter-4.0 及以上版本才支持Lua脚本&#xff1b; scripting API &#xff1f; scripting applets &#xff1f; 飞控条件&#xff1a;2 MB of flash and 70 kB of memory &#xff1b…

【使用 k 折叠交叉验证的卷积神经网络(CNN)】基于卷积神经网络的无特征EMG模式识别研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

前端一定要学的知识点-闭包

闭包是js面试中常问的问题&#xff0c;这篇文章希望能给大家帮助 闭包&#xff08;Closures&#xff09; 介绍 闭包是一种在 JavaScript 中常见的概念。它允许函数访问其词法作用域外部的变量&#xff0c;并在函数的生命周期内保持对这些变量的引用。通过闭包&#xff0c;我…

攻防世界-warmup

原题解题思路 只有一张图片&#xff0c;就查看源代码&#xff0c;有一个source.php。 查看source.php&#xff0c;白名单中还有一个hint.php。 hint.php告诉我们flag的位置ffffllllaaaagggg 但是直接跳转是没用的&#xff0c;构造payload。 http://61.147.171.105:55725/sourc…

JS逆向-某招聘平台token

前言 本文是该专栏的第56篇,后面会持续分享python爬虫干货知识,记得关注。 通常情况下,JS调试相对方便,只需要chrome或者一些抓包工具,扩展插件,就可以顺利完成逆向分析。目前加密参数的常用逆向方式大致可分为以下几种,一种是根据源码的生成逻辑还原加密代码,一种是补…

阿里云使用WordPress搭建个人博客

手把手教你使用阿里云服务器搭建个人博客 一、免费创建服务器实例 1.1 点击试用 点击试用会需要你创建服务器实例&#xff0c;直接选择默认的操作系统即可&#xff0c;点击下一步 1.2 修改服务器账号密码 二、创建云数据库实例 2.1 免费获取云数据库使用 2.2 实例列表页 在…