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

目录

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在释放空间前会调用析构函数完成空间中资源的清理。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言while 语句的基本格式是什么?

一、问题 C语⾔中有三种循环语句,while 语句是其中的⼀个,它的基本格式是怎样的呢? 二、解答 while 语句的⼀般形式为: while(表达式) 语句; 其中,表达式是循环条件,语句为循环体。 注意: …

uni-app 微信小程序:启用组件按需注入

原文地址:uni-app 微信小程序:启用组件按需注入 - 掘金 只需添加以下代码"lazyCodeLoading": "requiredComponents"

养娃到大学毕业要68万?不算不知道一算要起跳!

最近看到的新话题,第一反映就是养一个娃要这么多费用吗? 以我马上就要上大学的娃家长身份,索性粗针大线的做了一个预估,让我们一起来探讨一下吧: 现正在考虑娃是可以读国内正常的公办大学还是能读国内的合作办学大学…

【机器学习实战1】泰坦尼克号:灾难中的机器学习(一)数据预处理

🌸博主主页:釉色清风🌸文章专栏:机器学习实战🌸今日语录:不要一直责怪过去的自己,她曾经站在雾里也很迷茫。 🌼实战项目简介 本次项目是kaggle上的一个入门比赛 :Titani…

护眼灯到底有用吗知乎?5大超强实力护眼台灯测评推荐!

护眼台灯无疑是每个学子必备的学习用具,那到底有没有用呢?其实真正好的护眼灯在一定程度上对保护学生的眼睛来说肯定是有用的。当然前提是要选购到优质的护眼台灯,保障各项性能都是合格的,使用起来才安全放心。 一、护眼台灯是如何…

Python web框架fastapi数据库操作ORM(一)

文章目录 Fastapi ORM操作1、创建模型2、创建数据库连接配置文件3、启动项目4、根据模型类创建数据库表1. 初始化配置,只需要使用一次2. 初始化数据库,一般情况下只用一次3. 更新模型并进行迁移4. 重新执行迁移,写入数据库5. 回到上一个版本6…

uniapp+vue基于Android的图书馆借阅系统qb4y3-nodejs-php-pyton

uni-app框架:使用Vue.js开发跨平台应用的前端框架,编写一套代码,可编译到Android、小程序等平台。 框架支持:springboot/django/php/Ssm/flask/express均支持 前端开发:vue 语言:pythonjavanode.jsphp均支持 运行软件:idea/eclip…

【Javascript编程实操01】判断最大数、奇偶数、是否成年

目录 前言 1、求两个数的最大数 代码: 实现效果: 2、判断一个整数是偶数还是奇数 代码: 实现效果: 3、判断一个人的年龄是否满18岁 代码: 实现效果: 总结 前言 从今天开始正式进入了Web前端第二…

GitLab--Merge Request 权限管理

场景 团队在日常开发工作中需要进行分支管理,通常使用feature分支进行开发,然后依次合并到dev分支、release分支,整个代码合并过程不仅仅是代码合并还需要对代码进行审核,如果在线下进行审核合并,这样操作无法保留痕迹…

反射详解-获取构造方法-动态代理

反射是Java语言中的一个关键特性,它允许程序在运行时访问类、接口、字段和方法的信息,并且可以动态地调用方法或改变字段值。 以下是关于Java反射的一些主要方面: 类加载器(Class Loader): Java反射开始于…

内网穿透 nas/树莓派+ipv4服务器 (ipv6)

nas 1.有个服务器 2.有个nas https://github.com/snail007/goproxy/blob/master/README_ZH.md https://github.com/snail007/proxy_admin_free/blob/master/README_ZH.md 2个官网一个是程序,一个是网站 手册 https://snail007.host900.com/goproxy/manual/zh/#/?i…

Tiktok矩阵系统搭建的逻辑和源代码!

很多和我一样从事外贸工具开发的朋友都清楚,TikTok矩阵系统不仅确保了平台的高效运行,还为用户提供了个性化的内容推荐,从而大大提升了用户黏性,因此很多人都乐意去开发类似的工具,下面我们就来说说Tiktok矩阵系统搭建…

Vue3 在SCSS中使用v-bind

template 先创建一个通用的页面结构 <template><div class"v-bubble-bg"></div> </template>js 在JS中先对需要用的数据进行定义&#xff1a; 可以是参数&#xff0c;也可以是data <script setup>const props defineProps({bgCol…

[万字长文] 从 Vue 3 的项目模板学习 tsconfig 配置

文章目录 一、tsconfig.json 的作用二、基本介绍三、Vue 3 的 tsconfig.json 的结构分析1. 总配置 tsconfig.json2. Web 侧 tsconfig.app.jsona. 继承基础配置b. 包含和排除的文件c. 编译器选项 3. 测试 tsconfig.vitest.jsona. 继承的基础配置b. 包含和排除的文件c. 编译器选项…

Swiper实现轮播效果

swiper官网&#xff1a;https://3.swiper.com.cn/ <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title&…

苹果的“汽车梦”宣告失败,转战AI?能hold住吗?

文 | BFT机器人 一觉睡醒&#xff0c;苹果就宣布了一件爆炸性的新闻&#xff0c;那就是坚持多年和受到很多行业大佬支持和期待的“泰坦”宣布结束了&#xff01;将原有负责汽车项目的大部分主力军转战到AI核心上&#xff0c;这消息一出&#xff0c;业内外纷纷对苹果的这个决定…

仓储自动化新解:托盘四向穿梭车驶入智能工厂 智能仓储与产线紧密结合

目前&#xff0c;由于对仓库存储量的要求越来越高&#xff0c;拣选、输送以及出入库频率等要求也越来越高&#xff0c;对此&#xff0c;在物流仓储领域&#xff0c;自动化与智能化控制技术得以快速发展&#xff0c;货架穿梭车在自动库领域的应用越来越广泛。现阶段&#xff0c;…

从 iOS 设备恢复数据的 20 个iOS 数据恢复工具

作为 iPhone、iPad 或 iPod 用户&#xff0c;您可能普遍担心自己可能会丢失存储在珍贵 iOS 设备中的所有宝贵数据。数据丢失的原因多种多样&#xff0c;这里列出了一些常见原因&#xff1a; 1. iOS 软件更新 2. 恢复出厂设置 3. 越狱 4. 误操作删除数据 5. iOS 设备崩溃 …

CMake、OpenCV 和单元测试

我写了很多关于 CMake 的文章&#xff0c;如果你感兴趣&#xff0c;可以点击以下链接阅读&#xff1a; CMake VS MakeCMake&#xff1a;在构建世界掀起风暴现代 CMake 使用技巧CMake 交叉编译CMake 生成器已开启 我们将继续对 CMake 的探索&#xff0c;这篇文章技术性高&…

如何解决 C/C++ 编译器优化导致的编译BUG(程序崩溃)支援VC++/CLANG/GCC

本文仅适用于&#xff0c;有愿意、爱捣鼓的童靴。 因编译器优化导致编译BUG&#xff0c;即DEBUG下面无故障稳定工作&#xff0c;但RELESE下程序会在特定函数位置上崩溃。 这要求 C/C 开发人员拥有最基本的素质&#xff0c;需要能够承受&#xff0c;逐行审视编译器输出的目标平…