c/c++内存管理(详解) + new与delete的用法及底层

1:c/c++内存分布情况

        1.1:c/c++内存的分布图

        1.2:每个区域的用途及不同类型变量存储在那个区

        1.3:例题讲解

2:c++动态内存管理方式(new  delete)

        2.1:new的语法

        2.2:delete的语法

3:operator new函数与operator delete函数

4:new与delete的实现原理

5:定位new表达式初识

6:malloc/free与new与delete的区别

7:delete与delete[]的区别


声明:图片均来自网上

1:c/c++内存分布情况

1.1c/c++内存的分布图

        如下图:

        如上图所示:我们c/c++语言内存分布的区域有:内核空间,栈区,内存映射段,堆区,数据段(静态区),代码段(常量区),由于对一些区域不是很了解,所以我们在这里只会挑选一些在语言中经常使用的区域进行讲解:栈区,堆区,数据段(静态区),代码段(常量区)

        在了解上面每个区域的作用前我们需要知道为什么有不同的区域划分呢?

        在我们的生活中我们知道,在我们家乡,政府将每个地方分成不同的区域,而这些区域是用来发展不同的经济产业,满足不同的需求。

        就如家乡的区域划分一样,我们的c/c++语言划分区域是因为我们不同的数据,有不同的存储需求,而每个区域就能满足这些数据的需求。

    1.2:每个区域的用途及不同类型变量存储在那个区

        栈区:临时用的变量,函数栈桢,局部变量。

        堆区:我们向系统动态申请空间的地方,各种数据结构。

        数据段(静态区):全局变量,static定义的变量。

        代码段:各种只读常量,指令。


1.3:例题讲解

        答案:CCCAA        AAADAB

下面我们通过内存分布图来完成上面的习题。

        解析如上图。重点是我们需要理解每句话的内容,然后根据内容找到相对应的空间。

        栈是向下增长的地址变小,堆是想上增长的地址变大,堆栈相对而生。


2:new与delete的用法

        我们通过下面代码来学习new与delete的语法:

        

	// new + 类型  并未初始化 申请一个空间int* p1 = new int;//开辟一个空间的用法//申请多块空间  new + 类型[]int* p2 = new int[10];//开辟10个整形空间 并未初始化//开辟空间并初始化int* p3 = new int(1);int* p4 = new int[10]{ 1,2,3,4 };//初始化部分其它的空间全为0return 0;

new+类型开辟空间    new+类型[n]:开辟n个空间   对于一个空间的初始化用(),对于一堆空间的初始化为{}符号,new与malloc一样默认初始化为随机值。

以上为vs调试下的开辟空间。

总结:用new创建的对象,我们就用delete对象   new[] 对象------delete[] 对象。对于内置类型的对象申请/释放空间 与malloc/free除了用法上,没有区别。


3:operator new函数与operator delete函数

       new和delete是用户申请/释放空间的操作符 operator new与operator delete则是由系统提供的全局函数。  new的底层调用了 operator new函数申请空间,delete底层调用了operator delete函数释放空间。

       下图是 operator new函数的实现,我们可以知道operator new 底层调用了 malloc函数与使用了面向对象处理错误的方法

对比的来说operator delete的底层肯定调用了free函数来释放空间。

总结:operator new  =malloc+抛异常。operator delete =free


4:new和delete的实现原理

        对于内置类型申请/释放空间   new  = operator new    delete =operator delete,而他们本质上分别调用了 malloc与free函数,也就是说  对于内置类型成员  new =malloc  delete =free,只是他们在用法上面不同而已。

        而对于自定义类型对象来说:new = operator new+ 调用构造函数。delete =operator delete+调用析沟函数。

我们用vs代码来测试我们说的内容:

class Stack
{
public:Stack(int capacity = 4){_a = new int[capacity];cout << "Stack(int capacity = 4)" << endl;_top = 0;_capacity = 0;}~Stack(){cout << "~Stack()" << endl;delete _a;}
private:int* _a;int _top;int _capacity;};

上面是我们简写的栈

我们下面用它创建1个类对象

在这个案列中我们就可以发现,对于自定义类型对象使用new与delete,new底层实现是 构造+operator new(开空间), delete=operator delete +调用析沟


我们来仔细分析这个代码是如何申请内存的,如何两次使用new的。


5:定位new表达式

        在我们学习定位new的时候,我们先来回忆之前我们学过的知识点,构造函数只有在定义对象的时候才会被调用。

        假如我们先给对应的类对象开辟空间,那么我们之后如何初始化呢?代码如下

int main()
{Stack * p = (Stack* )malloc(sizeof(Stack));return 0;
}

   在这种情况下,我们并没有调用构造函数,那么我们该如何调用构造函数呢?

我们使用p->Stack(),是不行的,因为构造函数只有在定义对象的时候才能被调用。

这种时候如果我们想要调用构造函数,我们就必须使用定位new的知识点了。

定位new语法:new(申请空间address)构造函数调用方式

如下:new(p)Stack().

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

以后会补上定位new的使用场景。


6:malloc/free与new与delete的区别

1:new与delete是操作符,malloc与free是函数调用的时候需要包含相应的头文件。

2:malloc申请的空间不会初始化,new可以进行初始化。

3:malloc申请空间需要手动的计算开空间的大小,new 开辟对象类型[n],n表示要开辟多少个n对象.

4:malloc的返回值为(void*)使用的时候需要强转,new没有返回值。

5:malloc申请空间的时候失败返回NULL,而new失败我们只需要对他进行捕获异常即可。

6:申请自定义类型空间的时候,malloc/free只会申请/释放空间,而new=开空间+调用对应的构造函数,free=释放空间+调用析沟函数

7:delete与delete[]的区别

        首先我们要知道在用法上:delete-----new,delete[]------new[],这两个用法上最好是这样一一对应的,不然有时候程序就会崩溃。

其实当我们使用delete[]的时候,我们的编译器会多开辟一个整形大小的空间,这个空间用来记录我们之前开了多少个对象。

我们调用delete[]的时候,也会将这个多开辟空间给释放掉。

而如果没加[],就直接从p开始释放空间。

总结:new---delete  new [] ---delete[].

本章知识点分享完毕,感谢大家的耐心观看。

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

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

相关文章

python+selenium实现自动联网认证,并实现断网重连

pythonselenium实现自动联网认证&#xff0c;并实现断网重连 echo off python “E:\autoD\auto_login.py” 要使自动登录脚本在系统重启后自动运行&#xff0c;你可以使用Windows的任务计划程序来设置。以下是详细的步骤&#xff1a; 1. 保存脚本 首先&#xff0c;将你的Py…

【高分系列卫星简介——高分二号卫星(GF-2)】

高分二号卫星&#xff08;GF-2&#xff09; 高分二号&#xff08;GF-2&#xff09;卫星是中国自主研制的首颗空间分辨率优于1米的民用光学遥感卫星&#xff0c;具有亚米级空间分辨率、高定位精度和快速姿态机动能力等特点&#xff0c;达到了国际先进水平。以下是对高分二号卫星…

对Spring-AI系列源码的讲解

前言 今天&#xff0c;我们将开启对Spring-AI系列源码的讲解。请大家不急不躁&#xff0c;我会逐步深入&#xff0c;每次专注于一个知识点&#xff0c;以防让人感到困惑。 首先&#xff0c;源码的讨论自然离不开自动装配。有人可能会问&#xff0c;之前已经讲解过这个内容了&…

【JavaSE】八种基本数据类型及包装类

数据类型字节数位数值范围包装类默认值整型byte18-128&#xff0c;127Byte0short216&#xff0c;Short0int432&#xff0c;Integer0long864&#xff0c;Long0L浮点型float432Float0.0fdouble864Double0.0d布尔型boolean18true falseBooleanfalse字符型char2160&#xff0c;Char…

C++编程语言:基础设施:异常处理(Bjarne Stroustrup)

第 13 章 异常处理(Exception Handling) 目录 13.1 错误处理(Error Handling) 13.1.1 异常(Exceptions) 13.1.2 传统错误处理(Traditional Error Handling) 13.1.3 探索(Muddling Through) 13.1.4 异常的替代观点(Alternative Views of Exceptions) 13.1.4.1 异步…

DAY78服务攻防-数据库安全RedisCouchDBH2database未授权访问CVE 漏洞

知识点&#xff1a; 1、数据库-Redis-未授权RCE&CVE 2、数据库-Couchdb-未授权RCE&CVE 3、数据库-H2database-未授权RCE&CVE 前置知识 1、复现环境&#xff1a;Vulfocus(官方在线的无法使用&#xff0c;需要自己本地搭建) 官方手册&#xff1a;https://fofapr…

老牛码看JAVA行业现状

一、坏消息深化与反思&#xff1a; 1、技术瓶颈与框架局限&#xff1a;尽管低代码平台崭露头角&#xff0c;为开发效率带来新气象&#xff0c;但其全面普及尚需时日&#xff0c;Java技术栈的进化似乎陷入了暂时的停滞。开发者们渴望突破&#xff0c;却发现传统框架与模式已难以…

博图V16升级V19前后内存对比

升级V19后固件版本更新到4.6 存储存储空间拓展50% 下图是官方解释 打开博图查看前后对比

[笔记]某变频器,功能列表及参数表

产品代号&#xff1a;INVT GOODDRIVE&#xff0c;这家公司我的产品我似乎在特检院看到过&#xff1f;或者在某个地铁建设工地看到过。是深圳的。 1.产品功能点&#xff1a; 变频锥形电机控制、抱闸转矩验证&#xff1f;抱闸反馈零位检测行程限位超载防护轻载升速&#xff08;…

【超详细】基于YOLOv8训练无人机视角Visdrone2019数据集

主要内容如下&#xff1a; 1、Visdrone2019数据集介绍 2、下载、制作YOLO格式训练集 3、模型训练及预测 4、Onnxruntime推理 运行环境&#xff1a;Python3.8&#xff08;要求>3.8&#xff09;&#xff0c;torch1.12.0cu113&#xff08;要求>1.8&#xff09;&#xff0c…

8. 防火墙

8. 防火墙 (1) 防火墙的类型和结构 防火墙的类型和结构可以根据其在网络协议栈中的过滤层次和实现方式进行分类。常见的防火墙类型包括: 包过滤防火墙:工作在网络层(OSI模型的第3层),主要检查IP包头的信息,如源地址、目的地址、端口号等。电路级网关防火墙:工作在会话层…

idea2021git从dev分支合并到主分支master

1、新建分支 新建一个名称为dev的分支&#xff0c;切换到该分支下面&#xff0c;输入新内容 提交代码到dev分支的仓库 2、切换分支 切换到主分支&#xff0c;因为刚刚提交的分支在dev环境&#xff0c;所以master是没有 3、合并分支 点击push&#xff0c;将dev里面的代码合并到…

对时间序列SOTA模型Patch TST核心代码逻辑的解读

前言 Patch TST发表于ICLR23&#xff0c;其优势在于保留了局部语义信息&#xff1b;更低的计算和内存使用量&#xff1b;模型可以关注更长的历史信息&#xff0c;Patch TST显著提高了时序预测的准确性&#xff0c;Patch可以说已成为时序模型的基本操作。我在先前的一篇文章对P…

【掘金量化使用技巧】用日线合成长周期k线

掘金API中的接口最长的周期是‘1d’的&#xff0c;因此周线/月线/年线等数据需要自己进行合成。 基本思路 用日线合成长周期的k线只需要确定好合成的周期以及需要的数据即可。 周期: 一般行情软件上提供年k、月k、周k&#xff0c;我也选择年、月、周再加一个季度频率。 数据:…

Linux:终端(terminal)与终端管理器(agetty)

终端的设备文件 打开/dev目录可以发现其中有许多字符设备文件&#xff0c;例如对于我的RedHat操作系统&#xff0c;拥有tty0到tty59&#xff0c;它们是操作系统提供的终端设备。对于tty1-tty12使用ctrlaltF*可以进行快捷切换&#xff0c;下面的命令可以进行通用切换。 sudo ch…

GPU加速时代:如何用CuPy让你的Python代码飞起来?

你是不是也有这样的感受:明明写的Python代码很简洁,用NumPy处理数据也很方便,可是一跑起来就慢得像乌龟?尤其是当你面对庞大的数据集时,光是等结果出来,就已经耗掉大半天了。其实,我以前也是这么干的,直到我发现了CuPy,一个能让NumPy飞速跑起来的GPU加速神器。 你…

10. 排序

一、排序的概念及引用 1. 排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录…

基于SpringBoot的医院管理系统【附源码】

基于SpringBoot的医院管理系统&#xff08;源码L文说明文档&#xff09; 目录 4 系统设计 4.1 系统概述 4系统概要设计 4.1概述 4.2系统结构 4.3.数据库设计 4.3.1数据库实体 4.3.2数据库设计表 5系统详细实现 5.1 医生模块的实现 5.1.…

Mybatis 返回 Map 对象

一、场景介绍 假设有如下一张学生表&#xff1a; CREATE TABLE student (id int NOT NULL AUTO_INCREMENT COMMENT 主键,name varchar(100) NOT NULL COMMENT 姓名,gender varchar(10) NOT NULL COMMENT 性别,grade int NOT NULL COMMENT 年级,PRIMARY KEY (id) ) ENGINEInnoD…

【RocketMQ】一、基本概念

文章目录 1、举例2、MQ异步通信3、背景4、Rocket MQ 角色概述4.1 主题4.2 队列4.3 消息4.4 生产者4.5 消费者分组4.6 消费者4.7 订阅关系 5、消息传输模型5.1 点对点模型5.2 发布订阅模型 1、举例 以坐火车类比MQ&#xff1a; 安检大厅就像是一个系统的门面&#xff0c;接受来…