C++——内存管理(new和delete)详解

news/发布时间2024/9/20 7:47:12

目录

C/C++内存管理

案例:变量在内存中到底会在哪?

New和delete

Operator new和operator delete函数

New和delete的原理

对内置类型

对自定义类型

定位new

New/delete和malloc/free的区别


C/C++内存管理

        C/C++内存管理分布图:(从语言的角度来看,数据段也称为静态区,代码段也称为常量区)

        内存大小:理论上,32位计算机内存上限为4GB;64位计算机内存上限可达256T,实际上我们使用计算机一般为8G或16G或者32G,不会很大。

栈和堆细节:  

        栈区先定义的变量放到栈底地址高后定义的变量放到栈顶地址低,因此是栈是向下生长的,堆区则相反

        栈区主要存在局部变量和函数参数,其空间的管理由编译器自动完成,无需手动控制,堆区是自己申请。

        堆大小受限于操作系统,而栈空间一般由系统直接分配。

        栈一般是进行静态分配的,但也可以通过函数_alloca进行动态分配,不过注意,所分配空间不能通过free或delete进行释放,而堆无法静态分配,只能动态分配。

         在C语言中我们用malloc/calloc/realloc和free来在堆上管理堆上的空间,但在c++中进行了更新。在C++中我们用New和delete来管理堆上的空间。

        Malloc和new的最大差别是:C语言malloc失败后会返回NULL,C++New失败后会自动报异常。

        注意:使用malloc是需要头文件malloc.h,只是平时这个头文件已经被其他头文件所包含了,用的时候很少单独引入。

案例:变量在内存中到底会在哪?

请填写下列问题:

        globalVar在哪里?__静态区__  staticGlobalVar在哪里?_静态区___

        staticVar在哪里?__静态区__  localVar在哪里?____

        num1 在哪里?____

        char2在哪里?____ * char2在哪里?___

用数组存储字符串,会在代码段生成一串字符,然后到栈上开辟一段空间,把内容拷贝进去

        pChar3在哪里?____ * pChar3在哪里?_代码段(常量区)___

用指针则是存放 代码段内存放字符串的地址,所以解引用地址会在代码段

        ptr1在哪里?____ * ptr1在哪里?____

prt1变量是在栈区创建的,所以在栈上,但申请的空间在堆上

        sizeof(num1) = __40__;

        sizeof(char2) = _5___;   strlen(char2) = __4__;(sizeof(数组)就是整个数组的大小

        sizeof(pChar3) = _4/8___;   strlen(pChar3) = _4___;(sizeof(指针)则是看几位计算机

        sizeof(ptr1) = __4/8__;

New和delete

        创建单个对象:new 类型(内容)创建数组:new 类型[大小]{内容},开辟类对象的数组时(该类对象有用户写的析构函数,默认生成的不行),会在前面额外开辟4字节空间,用于存放类对象数组有多少个元素,让delete数组时,调用类的析构函数时知道要调用几次。C++把new当做一个操作符而不是函数

        Delete也分为两种,释放单个空间:delete 对象名;释放一个数组:delete[] 对象名

        New和delete的使用方式如下:

        在C++中,我们new一个类对象,编译器会自动调用该类的构造函数。这样就不需要像C语言malloc一个空间然后赋值那么麻烦。Delete也会调用该类的析构函数。

注意:new和delete一定要匹配使用,即new数组要用delete数组来释放。

        如果不匹配使用,对于内置类型没有自己写析构函数的类一般不会出错(默认生成析构函数是系统合成的没有作用的析构函数,所以系统什么也不做,只用释放空间,内置类型同理

        对于有自己写析构函数的类,delete会调用析构函数,而new数组本来应该匹配delete数组来释放,让编译器调用多次析构函数,但如果我们没有匹配使用,如下图,只用了delete a1,编译器只会调用一次析构函数,编译虽然能通过,但是运行会出断言错误。

Operator new和operator delete函数

        Operator new和operator delete函数是系统提供的全局函数,它们实际上是new和delete的底层代码,new底层会调用operator new函数来申请空间;delete底层调用operator delete函数来释放空间

        Operator new底层代码也是通过malloc来开辟空间,即对malloc的封装,如果空间不够,则判断一下malloc是否返回NULL;如果申请内存失败了,这里会抛出bad_alloc类型异常,也就是new失败之后返回的异常。Operator delete同理,是对free的封装

        总之,operator new不是为我们准备的,而是为new准备的,主要是用来返回开辟空间异常的

New和delete的原理

对内置类型

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

对自定义类型

New:

        调用operator new函数申请空间,然后在申请的空间上执行构造函数,完成对象的构造。

Delete:

        在空间上执行析构函数,完成对象中资源的清理工作,然后调用operator delete函数释放对象的空间

New[N]:

        调用operator new[]函数,在operator new[]中实际调用operator new函数完成对N个对象空间的申请,在申请的空间上执行N次构造函数。

Delete[]:

        在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理。(N是多少编译器会知道,不需要填),然后调用operator delete[]释放空间,实际上在operator delete[]中会调用operator delete来释放空间。

定位new

        定位new表达式是已分配的原始内存空间中调用构造函数初始化一个对象。使用方法为:new(指针,指向开辟的空间)类型(要初始化的值),使用情况如下图所示:

New/delete和malloc/free的区别

区别:

  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.bcls.cn/kAEJ/9902.shtml

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

相关文章

2024牛客寒假算法基础集训营4

目录 A.柠檬可乐 B.左右互博 C.冬眠 D.守恒 E.漂亮数组 F.来点每日一题 G.数三角形&#xff08;easy&#xff09; A.柠檬可乐 阅读理解题&#xff0c;依照题目直接模拟即可 void solve(){int a,b,k; cin>>a>>b>>k;if(a>k*b) cout<<"go…

【Java】基本数据类型、包装类与字符串间的转换 例题

写在前面&#xff1a; 关于这道题&#xff0c;初见感觉有点cpu烧坏了&#xff0c;准确来说是看了网上的一些讲解都感觉不尽人意。自己整理了一下&#xff0c;希望能帮助到大家。 题目&#xff1a; 如下两个题目输出结果相同吗&#xff1f;各是什么。 Object o1 true ? new…

Java毕业设计-基于springboot开发的Web社区医院管理服务系统-毕业论文+答辩PPT(有源代码)

文章目录 前言一、毕设成果演示&#xff08;源代码在文末&#xff09;二、毕设摘要展示1.开发说明2.需求分析3、系统功能结构 三、系统实现展示1、系统功能模块2、管理员功能模块3、用户功能模块4、医生功能模块 四、毕设内容和源代码获取总结 Java毕业设计-基于springboot开发…

CGI程序与ShellShock漏洞

CGI是什么&#xff1f; CGI&#xff08;通用网关接口&#xff0c;Common Gateway Interface&#xff09;程序是一种用于在Web服务器上执行动态内容的技术。与服务器上普通的后端代码相比&#xff0c;CGI程序有几个区别&#xff1a; 执行环境&#xff1a; CGI程序在服务器上作为…

从CPU缓存结构到原子操作

一、CPU缓存结构 1.1 CPU的多级缓存 因为CPU的计算速度非常快&#xff0c;但内存的访问速度相对较慢。因此&#xff0c;如果CPU每次都要从内存读取数据&#xff0c;会造成大量的等待时间&#xff0c;降低整体性能。 通过引入多级缓存&#xff0c;可以在CPU和内存之间建立数据…

3月1号代码随想录二叉搜索树中的插入操作

301.二叉搜索树中的插入操作 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 &#xff0c;新值和原始二叉搜索树中的任意节点值都不同。 注意&#xff0c;…

html样式排版

<template><div class"box"><div class"header">头部</div><div class"main"><div class"left">菜单</div><div class"right"><div class"right-contentr"&g…

Redis——服务器

Redis服务器负责与多个客户端建立网络连接&#xff0c;处理客户端发送的命令请求&#xff0c;在数据库中保存客户端执行命令所产生的数据&#xff0c;并通过资源管理来维持服务器自身的运行。 一. 命令请求的执行过程 一个命令请求从发送到获得回复过程中&#xff0c;客户端和服…

【精品】集合list去重

示例一&#xff1a;对于简单类型&#xff0c;比如String public static void main(String[] args) {List<String> list new ArrayList< >();list.add("aaa");list.add("bbb");list.add("bbb");list.add("ccc");list.add(…

数据之光:探索数据库技术的演进之路

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua&#xff0c;在这里我会分享我的知识和经验。&#x…

09-Java组合模式 ( Composite Pattern )

Java组合模式 摘要实现范例 组合模式&#xff08;Composite Pattern&#xff09;&#xff0c;又叫部分整体模式&#xff0c;是用于把一组相似的对象当作一个单一的对象 组合模式依据树形结构来组合对象&#xff0c;用来表示部分以及整体层次 组合模式创建了一个包含自己对象组…

Mac 重新安装系统

Mac 重新安装系统 使用可引导安装器重新安装&#xff08;可用于安装非最新的 Mac OS&#xff0c;系统降级&#xff0c;需要清除所有数据&#xff09; 插入制作好的可引导安装器&#xff08;U盘或者移动固态硬盘&#xff09;&#xff0c;如何制作可引导安装器将 Mac 关机将 Ma…

SpringBoot实现短链跳转

目录 1.背景介绍 2.短链跳转的意义 3.SpringBoot中的代码实现 1.建议短链-长链的数据库表&#xff1a;t_url_map: 2.映射实体 3.Dao层实现 4.Service层实现 5.Controller层实现 3.结果测试 4.问题 1.背景介绍 短链跳转是一种通过将长链接转换为短链接的方式&…

Socket网络编程(一)——网络通信入门基本概念

目录 网络通信基本概念什么是网络&#xff1f;网络通信的基本架构什么是网络编程?7层网络模型-OSI模型什么是Socket&#xff1f;Socket的作用和组成Socket传输原理Socket与TCP、UDP的关系CS模型(Client-Server Application)报文段牛刀小试&#xff08;TCP消息发送与接收&#…

OceanMind海睿思-知信版本升级:多轮对话+LLM加速!

OceanMind海睿思-知信 产品能力全新升级&#xff1a; ❖ 知识库增加多轮对话能力&#xff0c;给用户带来更“人性化”的问答体验 ❖ 自研大模型推理加速机制&#xff0c;为大模型回答提速&#xff0c;减少用户等待时间消耗 1 多轮对话升级 基于“RAG大模型”框架的知识库问…

ChatGPT科研绘图丨散点图、柱状图、小提琴图、箱型图、雷达图、玫瑰图、气泡图、森林图、三元图、三维图等各类科研图

以ChatGPT、LLaMA、Gemini、DALLE、Midjourney、Stable Diffusion、星火大模型、文心一言、千问为代表AI大语言模型带来了新一波人工智能浪潮&#xff0c;可以面向科研选题、思维导图、数据清洗、统计分析、高级编程、代码调试、算法学习、论文检索、写作、翻译、润色、文献辅助…

Rocky Linux 运维工具 vim

一、vim的简介 vi​m是一种文本编辑器。它提供了丰富的编辑功能&#xff0c;包括插入、删除、替换文本、搜索和查找等。使用键盘命令和模式切换&#xff0c;以实现高效的文本编辑操作。 二、vim的参数说明 序号视图命令描述1命令视图i在当前光标位置进入‘INSERT视图’2命令视…

2024年四川媒体新闻发布渠道,媒体邀约资源表

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 四川有哪些媒体新闻发布渠道&#xff0c;媒体邀约资源表&#xff1f; 2024年四川媒体新闻发布渠道&#xff0c;媒体邀约资源表 四川本地媒体&#xff1a;如四川日报、华西都市报、成都商…

浅谈MySQL的B树索引与索引优化

MySQL的MyISAM、InnoDB引擎默认均使用B树索引&#xff08;查询时都显示为“BTREE”&#xff09;&#xff0c;本文讨论两个问题&#xff1a; 为什么MySQL等主流数据库选择B树的索引结构&#xff1f;如何基于索引结构&#xff0c;理解常见的MySQL索引优化思路&#xff1f; 为什…

c语言经典测试题8

在c语言经典测试题6的第一题&#xff0c;大家是否想过可不可以将递归参数改为s呢&#xff1f;或许有的人已经试过了&#xff0c;但是发现好像不会有结果&#xff0c;其实是因为s为后置&#xff0c;先试用后加1&#xff0c;然而我们这个是在s出了函数之后才会运行加1操作&#x…
推荐文章