C++【new delete】【operator new operator delete】

目录

数据段存储位置的小复习

new 和 delete

operator new 和 operator delete

new和delete调用operator new和operator delete

new [ ] 和 delete [ ]的原理


数据段存储位置的小复习

全局变量和静态变量都在静态区,也称数据段

全局变量int x = 0 和 全局静态变量static int c = 0 的区别

int x = 0 可以在所有文件可以用,而static int c = 0 只能在当前文件可用

char num[] ="abcde";这行代码中的 *num在计算机里的什么地方

因为在赋值的时候,常量”abcde" 会拷贝一份给num,此时*num就是拷贝常量区的字符串内容

所以*num在栈上面


new 和 delete

动态申请一个int空间
int* p1 = new int动态申请一个int空间,并初始化为10
int* p2 = new int(10);动态申请十个int空间
int* p3 = new int[10];多个数据初始化,例如
int* p4 = new int[3]{1,2,3};

 如果不初始化的话,系统不会帮你初始化,因为它只是帮我们开空间

如果没有初始化完全,就好比我开了10个空间,但我值初始化了3个,其它的便会默认初始化0

删除的话,有方括号要带方括号,没方括号的可不带

delete p1;
delete p2;
delete[] p3;
delete[] p4;

引用new和delete的原因是:

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

eg:我们有一个A类

只是malloc的话:

A* p = (A*)malloc(sizeof(A));

我们怎么对它初始化,初始化不了啊,它甚至都没有构造函数的概念,怎么调用啊

new的作用:

  1. 开空间;
  2. 调用默认构造函数; 
  3. 可以显示调用

现在来展示一下3

A* a = new A(1);

 还可以同时开辟多个对象

A aa1(1);
A aa2(1);
A aa3(1);A* p1 = new A[3]{aa1,aa2,aa3};
A* p2 = new A[3]{A(2),A(2),A(2)};
A* p3 = new A[3]{3,3,3};

 所以,new的本质就是开空间和调用构造函数初始化

delete的本质就是调用析构和释放空间

class Stack {
private:int* _a;int _top;int _capacity;
public:Stack(int capacity=4){cout << "我调用了构造函数" << endl;_a = new int[capacity];_top = 0;_capacity = capacity;}~Stack() {cout << "析构!启动!" << endl;delete[] _a;_a = nullptr;_top = 0;_capacity = 0;}
};
	Stack* p = new Stack;delete p;

我们都知道,new的主要功能是开空间+调用构造函数,

但是在Stack*  p  = new Stack;这条语句中,它不是已经先new了一下吗,那么构造函数里又new的是什么,delete又该咋办

 构造的时候第一次new的是类的空间,第二次new的_a指向的空间

调用构造,构造的有_a指向的空间

释放的时候第一次delete的是_a指向的空间,第二次是p指向的空间

析构的有_a指向的空间


operator new 和 operator delete

new和delete是用户进行动态内存申请和释放的操作符,operator new和operator delete是系统提供的全局函数。

new是底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间

operator new和operator delete不是对new和delete的重载,它们就只是全局函数

可以认为封装了malloc和free,也就是说,operator new和operator delete的功能是跟malloc和free的功能一样的,只不过给它加了一个抛异常的功能

 

operator new和operator delete只负责开空间,并不负责调用构造函数和析构函数

  那既然malloc和operator那么相似,为什么不直接用malloc呢

那是因为malloc如果失败了,返回的是0,在C++中,即面向对象编程的过程中,出现了错误不能只返回0,而是要抛异常,malloc抛不了一场,但operator new能抛异常,所以选择operator new


new和delete调用operator new和operator delete

所以,在Stack* p = new Stack这串代码中,可以很清楚的看到

new先调用了operator new这个函数,然后再去调用Stack()这个构造函数

此种行为就是new的功能:开空间+构造函数 

同理

delete也是先调用了~stack(),然后再调用operator delete()函数

此种行为就是delete功能:释放类内开辟的空间,再释放类

一开始,我们会找不到operator delete函数调用,别急,我们进去(07FF7F2331532h)这个地址里面看看

再进去框框里面的地址,进到析构内部 

我们平常不会用operator new和operator delete,只是会间接调用


new [ ] 和 delete [ ]的原理

new Stack[10] 中,new只调用了一次operator new[ ] ,operator new [ ]是封装了operator new的函数,里面创建了有10个Stack类大小的空间

但是,调用构造函数调用了10次

delete[ ]  原理类似

为何是16,为何不是12,,我们知道*p3相当于p3[0],但是一个Stack,最多才12字节,为什么会多出4字节呢?

原因是:我们进入内存来去查看

自定义类型的时候,new的时候会多开四个字节,为了给delete[ ]准备,因为delete不知道

告诉它之后,就告诉delete [ ] 先调用10个析构函数,再去调用operator delete [ ]

operator delete [ ] 再去调用operator delete ,operator delete 再去调用free( )

free需要想办法,将开始的地址往后减到标记数量的那块地址上,再开始free( )

因为多了四字节的原因,因此在使用delete 和 delete[ ]  的时候,需要严格按照与new和 new[ ] 配对来完成释放空间的工作

比如,如果,我在开空间的时候用的是new [ ] ,而在释放空间的时候用的是 delete ,结果就会崩溃

原因是,delete识别不到多的四字节,导致在释放位置的时候到不了标注开了多少块空间的那个地址位置,所以漏了4字节空间没释放,最后导致崩溃。

析构函数可以显示调用,构造函数一般不能被显示构造

但可以通过定位new (placement-new)来显示调用构造函数,这个涉及到内存池

以上便是本次博文的学习内容,如有错误,还望各位大佬指点出来,谢谢阅读

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

全网最实用--神经网络各个组件以及效率指标 (含代码助理解,粘贴即用)

文章目录 一、神经网络相关组件0.前奏1.全连接层&#xff08;Fully Connected Layer, FC&#xff09;/密集层&#xff08;Dense Layer&#xff09;:2.卷积层&#xff08;Convolutional Layer, Conv&#xff09;:a.一维卷积b.二维卷积c.分组卷积 3.池化层&#xff08;Pooling La…

JavaWeb系列二十三: web 应用常用功能(文件上传下载)

文件上传下载 基本介绍文件上传基本原理文件上传应用实例文件上传注意事项和细节 文件下载基本原理文件下载应用实例文件下载注意事项 ⬅️ 上一篇: JavaWeb系列二十二: 线程数据共享和安全(ThreadLocal) &#x1f389; 欢迎来到 JavaWeb系列二十三: web 应用常用功能(文件上传…

数据结构:基础概念

一、相关概念 概念 相互之间存在一种或多种特定关系的数据元素的集合。 逻辑结构 集合&#xff1a;所有数据在同一个集合中&#xff0c;关系平等。 线性&#xff1a;数据和数据之间是一对一的关系 树&#xff1a; 一对多 图&#xff1a;多对多 物理结构(在内存当中的存储关系)…

堆的相关特点

一.建堆的两种方法 给定一个数组&#xff0c;其中数组里面的元素个数是n个如何能够把这个数组建立成为一个堆&#xff0c;今天探讨两种方法&#xff0c;分别是向上调整法和向下调整法&#xff0c;分别探讨他们的时间复杂度 向上调整法&#xff08;以小堆为例&#xff09; 回…

Spring系列-04-事件机制,监听器,模块/条件装配

事件机制&监听器 SpringFramework中设计的观察者模式-掌握 SpringFramework 中, 体现观察者模式的特性就是事件驱动和监听器。监听器充当订阅者, 监听特定的事件&#xff1b;事件源充当被观察的主题, 用来发布事件&#xff1b;IOC 容器本身也是事件广播器, 可以理解成观察…

create-vue源码学习之 gradient-string 渐变色打印

效果 在使用 create-vue 脚手架时&#xff0c;想实现如下的打印效果。 探究过程 翻到源码里看到这一行 没错&#xff0c;绿色部分就是告诉我们如何生成的。可以看到引入了 gradient-string 包 于是乎&#xff0c;我来试试 pnpm i gradient-string pnpm i --save-dev …

1.4、存储系统

目录 存储器的层次结构外存&#xff08;辅存&#xff09;内存CPU的寄存器Cache总结举例局部性原理 练习题 高速缓存Cache总结举例总结 练习题 Cache的地址映像方法直接相联映像全相联映像组相联映像练习题 Cache替换算法Cache页面淘汰算法Cache的读写过程练习题 磁盘总结固态硬…

人工智能(AI)在办公场所的广泛应用

人工智能&#xff08;AI&#xff09;在办公场所的广泛应用正逐步改变着我们的工作方式和效率。随着技术的进步&#xff0c;越来越多的公司和组织开始采用各种AI技术来优化工作流程、提升生产力&#xff0c;并提供更好的用户体验。以下是人工智能在办公方面的一些主要作用和影响…

Ecovadis评估的流程是什么

Ecovadis评估流程是一个全面、系统且注重细节的过程&#xff0c;旨在为企业提供关于其可持续性表现的深入洞察。这一评估不仅覆盖了企业在环境、社会和治理方面的多个方面&#xff0c;还强调了持续改进的重要性&#xff0c;确保企业能够不断提升其CSR&#xff08;企业社会责任&…

社交圈子聊天交友系统搭建社交app开发:陌生交友发布动态圈子单聊打招呼群聊app介绍

系统概述 社交圈子部天交友系统是一个集成即时通讯、社区互动、用户管理等功能的在线社交平台。它支持用户创建个人资料&#xff0c;加入兴趣围子&#xff0c;通过文字、图片、语音、视频等多种方式进行交流&#xff0c;满足用户在不同场景下的社交需求 核心功能 -&#xff0c;…

Window系统下MySQL安装教程

1、MySQL各版本介绍 MySQL Community Edition MySQL Community Edition 是MySQL官方发布的免费版本&#xff0c;适用于个人用户和小型团队使用。它包含了基本的数据库功能&#xff0c;如创建表、插入数据、查询数据等。 MySQL Enterprise Edition MySQL Enterprise Edition 是…

【数据结构】AVL树(图文解析 + 代码实现)

目录 1、AVL树的概念 2、AVL树结点的定义 3、AVL树的插入 4、AVL树的旋转 4.1 左单旋 4.2 右单旋 4.3 右左双旋 4.4 左右双旋 5、AVL树的验证 6、AVL树的性能 前面对map/multimap/set/multiset进行了简单的介绍&#xff0c;会大仙&#xff0c;这几个容器有个共同点是…

【AI大模型】程序员AI的未来——Copilot还是Claude3.5 Sonnet?

近期&#xff0c;Anthropic发布了Claude 3.5 的“大杯”模型 —— Claude 3.5 Sonnet&#xff01; 这次发布的 Sonnet 代表意大利的“十四行诗”&#xff0c;结构复杂&#xff0c;在智能水平、功能多样性和处理能力上都有所提升&#xff0c;能够应对更复杂的认知任务&#xff…

解决VS2019+Qt联合开发双击Resource Files弹不出资源编辑器问题

目录 一、右键Resource.qrc文件 二、选择打开方式 三、鼠标选择Qt Resource Editor&#xff0c;并设置为默认值 四、最后点击确定&#xff0c;再次双击qrc文件&#xff0c;成功打开 最近在开发中&#xff0c;遇见一个问题&#xff0c;在VS联合Qt开发时&#xff0c;需要添加…

前后端分离项目部署,vue--nagix发布部署,.net--API发布部署。

目录 Nginx免安装部署文件包准备一、vue前端部署1、修改http.js2、npm run build 编译项目3、解压Nginx免安装,修改nginx.conf二、.net后端发布部署1、编辑appsetting.json,配置跨域请求2、配置WebApi,点击发布3、配置文件发布到那个文件夹4、配置发布相关选项5、点击保存,…

推荐一款基于 SpringBoot2 的后台管理系统脚手架,非常轻量简单(附源码)

前言 在现代软件开发中&#xff0c;后台管理系统是企业数字化转型的关键组成部分。然而&#xff0c;现有软件常常存在一些痛点&#xff0c;如复杂的权限管理、缺乏灵活的工作流配置、监控和日志功能不完善等。此外&#xff0c;许多系统study 成本高&#xff0c;依赖关系复杂&a…

VS2015加断点(红色),修改过后,断点变为白色不能命中

实际这个问题是因为&#xff1a;源文件和原始版本不同。解决方法有二&#xff1a; 一&#xff0c;在断点上右键&#xff0c;选择“位置”》勾选”允许源代码与原始版本不同&#xff1b; 二&#xff0c;点击菜单栏“调试”》“选项和设置”》“常规”》去掉“要求源文件与原始…

MINE:Mutual Information Neural Estimation

Mutual Information Neural Estimation 摘要 文章认为高维连续随机变量之间的互信息可以通过在神经网络上梯度下降优化得到。 文中提出了互信息估计器(Mutual Information Neural Estimator),它在维度和 样本大小上都是可伸缩的&#xff0c;可以通过反向传播训练的&#xff0…

OCC 布尔运算

目录 一、裁剪原理 二、使用详解 1. 差集 (Cut) 2. 联合 (Fuse/Union) 3. 交集 (Common/Intersection) 三、例子 1、两个盒子裁剪 2、任意面裁剪 四、总结 一、裁剪原理 OpenCASCADE (OCC) 中的裁剪(Boolean Cut)原理主要基于布尔运算。布尔运算是计算机图形学中的…

力扣第二十四题——两两交换链表中的节点

内容介绍 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4] 输出&#xff…