当前位置: 首页 > article >正文

【C++初阶】第5课—动态内存管理

文章目录

  • 1. 内存分布
  • 2. C语言动态内存管理
  • 3. C++内存管理方式
    • 3.1 new/delete操作内置类型
    • 3.2 new和delete操作自定义类型
  • 4. operator new和operator delete函数
  • 5. new和delete的实现原理
  • 6. malloc/free和new/delete的区别
  • 7. 定位new表达式(了解即可)

1. 内存分布

  先来做一个关于内存的题吧

  • 题目

在这里插入图片描述


  • 答案

在这里插入图片描述


在这里插入图片描述


2. C语言动态内存管理

  • 之前在C语言阶段学了动态管理内存的三种方式malloc、calloc、realloc,回顾一下

在这里插入图片描述


3. C++内存管理方式

  • C++不仅继承了C语言的内存管理方式,而且还提出了自己的内存管理方式:通过new和delete操作符进行内存管理

3.1 new/delete操作内置类型

  • 单个元素的开辟内存和释放内存:new和delete实现
  • 多个元素的开辟内存:new 类型[元素个数]多个元素的释放:delete[]

在这里插入图片描述


在这里插入图片描述


3.2 new和delete操作自定义类型

  • new和delete对于自定义类型,会分别调用类的默认构造和析构,这是和malloc和free最大的区别
  • new和delete对于内置类型不会初始化。但是对于自定义类型是一定会初始化,因为它要调用默认构造,没有默认构造会报错

在这里插入图片描述


  • 对于类的多参数

在这里插入图片描述


4. operator new和operator delete函数

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

在这里插入图片描述


  • 从汇编底层指令可以看出,operator new和operator delete是用来实现new和delete的,空间申请失败则会抛出异常,编译器捕获到异常则会进行相应的处理,这里先简单了解下

5. new和delete的实现原理

  • 对于内置类型,new和malloc,delete和free基本一样,不同的是:new/delete申请和释放的是单个元素的空间,new[ ]和delete[ ]申请的是连续的空间,而且new在申请空间失败时会抛出异常,malloc则会返回NULL
  • 对于自定义类型
  • new的原理:
  • 调用operator new函数申请空间
  • 在申请的空间上执行构造函数,完成对象的构造
  • delete的原理:
  • 在空间上执行析构函数,完成对象中资源的清理工作
  • 调用operator delete函数释放对象的空间
  • new[T]的原理:
  • **调用operator new[ ]函数,在operator new[ ]中实际调用operator new函数完成N个对象空间的申请 **
  • 在申请的空间上执行N次构造函数
  • delete[T]的原理:
  • 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
  • 调用operator delete[ ]释放空间,实际在operator delete[ ]中调用operator delete来释放空间

6. malloc/free和new/delete的区别

  • 共同点:都是从堆上申请空间,并且需要用户手动释放
  • 不同点:malloc和free是函数,而new和delete是操作符
  • malloc申请的空间的同时不能初始化,而new可以
  • malloc申请空间时,需要手动计算空间大小并传递,而new只需要给出类型,如果是多个对象,在[ ]中添加对象个数即可
  • malloc的返回值是void*,使用时需要进行强转,而new不需要,new后跟的就是空间类型
  • malloc申请失败时会返回NULL,而new’失败会抛出异常,捕获异常即可
  • 申请自定义类型空间对象时,malloc/free只会开辟空间、释放空间,不会调用构造和析构,而new在申请空间对象时会调用构造函数对对象进行初始化,delete会调用析构函数对空间中的资源进行释放,然后释放该空间

在这里插入图片描述


7. 定位new表达式(了解即可)

  • 定位new表达式是在已经分配内存的原始空间中调用构造函数来初始化一个对象
  • new(place_address)type或者new(place_address)type(initializer-list)
  • place_address必须是一个指针,initializer-list是类型的初始化列表
  • 定位new表达式一般配合内存池使用,这是因为内存池分配出来的内存没有初始化,如果是自定义类型对象,需要借助new定位表达式进行显式构造函数进行初始化
  • 这里简单提两句,内存池呢其实就是从堆中分出一块空间,以供那些频繁向堆申请空间的对象使用,这个后面学习Linux可能细讲

在这里插入图片描述



http://www.kler.cn/a/417662.html

相关文章:

  • 【k8s深入理解之 Scheme 补充-1】理解 Scheme 中资源的注册以及 GVK 和 go 结构体的映射
  • CCF 第一届算法竞赛 CACC 考题回忆
  • Paper -- 建筑物高度估计 -- 基于深度学习、图像处理和自动地理空间分析的街景图像建筑高度估算
  • 【人工智能-科普】图神经网络(GNN):与传统神经网络的区别与优势
  • spring-boot-maven-plugin 标红
  • C++11 http服务端和客户端库cpp-httplib
  • 混乱原理与程序设计。
  • clickhouse 使用global in 优化 in查询
  • 【VUE3】新版Vue3+ElementPlus全家桶开发视频项目实战
  • vxlan 手工隧道(头端复制)
  • burpsuite功能模块学习(2)
  • 后台管理-动态路由配置以及用户权限管理(vue3+element plus+koa+Sequelize )
  • android将pcm byte[]通过Librtmp进行rtmp推流
  • 【Flink-scala】DataStream编程模型之窗口计算-触发器-驱逐器
  • 深度学习:在PyTorch中进行模型验证完整流程
  • 【问题】webdriver.Chrome()设置参数executable_path报不存在
  • HDMI协议
  • AI是泡沫吗
  • Python语法基础(五)
  • 创建模态对话框窗口
  • SpringBoot 框架下的新冠密接者跟踪系统:卓越性能与稳定性保障
  • 【Python网络爬虫笔记】6- 网络爬虫中的Requests库
  • tomcat控制台中文乱码的解决方法
  • 使用LabVIEW2019x64的IMAQdx调用工业相机采图(二)
  • DataWhale—PumpkinBook(TASK07支持向量机)
  • 记录Threadlocal使用