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

【C++ 面试 - 内存管理】每日 3 题(三)

✍个人博客:Pandaconda-CSDN博客

📣专栏地址:http://t.csdnimg.cn/fYaBd

📚专栏简介:在这个专栏中,我将会分享 C++ 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

7. 堆和栈的区别 

  1. 申请方式不同

    1. 栈由系统自动分配。

    2. 堆是自己申请和释放的。

  2. 申请大小限制不同

    1. 栈顶和栈底是之前预设好的,栈是向栈底扩展,大小固定,可以通过 ulimit -a 查看,由 ulimit -s 修改。

    2. 堆向高地址扩展,是不连续的内存区域,大小可以灵活调整。

  3. 申请效率不同

    1. 栈由系统分配,速度快,不会有碎片。

    2. 堆由程序员分配,速度慢,且会有碎片。

栈空间默认是 4M,堆区一般是 1G - 4G。

管理方式堆中资源由程序员控制(容易产生 memory leak)栈资源由编译器自动管理,无需手工控制
内存管理机制系统有一个记录空闲内存地址的链表,当系统收到程序申请时,遍历该链表,寻找第一个空间大于申请空间的堆结点,删除空闲结点链表中的该结点,并将该结点空间分配给程序(大多数系统会在这块内存空间首地址记录本次分配的大小,这样 delete 才能正确释放本内存空间,另外系统会将多余的部分重新放入空闲链表中)只要栈的剩余空间大于所申请空间,系统为程序提供内存,否则报异常提示栈溢出。(这一块理解一下链表和队列的区别,不连续空间和连续空间的区别,应该就比较好理解这两种机制的区别了)
空间大小堆是不连续的内存区域(因为系统是用链表来存储空闲内存地址,自然不是连续的),堆大小受限于计算机系统中有效的虚拟内存(32bit 系统理论上是 4G),所以堆的空间比较灵活,比较大栈是一块连续的内存区域,大小是操作系统预定好的,windows 下栈大小是 2M(也有是 1M,在编译时确定,VC 中可设置)
碎片问题对于堆,频繁的 new/delete 会造成大量碎片,使程序效率降低对于栈,它是有点类似于数据结构上的一个先进后出的栈,进出一一对应,不会产生碎片。(看到这里我突然明白了为什么面试官在问我堆和栈的区别之前先问了我栈和队列的区别)
生长方向堆向上,向高地址方向增长。栈向下,向低地址方向增长。
分配方式堆都是动态分配(没有静态分配的堆)栈有静态分配和动态分配,静态分配由编译器完成(如局部变量分配),动态分配由 alloca 函数分配,但栈的动态分配的资源由编译器释放,无需程序员实现。
分配效率堆由 C/C++ 函数库提供,机制很复杂。所以堆的效率比栈低很多。栈是其系统提供的数据结构,计算机在底层对栈提供支持,分配专门寄存器存放栈地址,栈操作有专门指令。

形象的比喻

栈就像我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。

堆就像是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

8. 你觉得堆快一点还是栈快一点?

毫无疑问是栈快一点。

因为操作系统会在底层对栈提供支持,会分配专门的寄存器存放栈的地址,栈的入栈出栈操作也十分简单,并且有专门的指令执行,所以栈的效率比较高也比较快。

而堆的操作是由 C/C++ 函数库提供的,在分配堆内存的时候需要一定的算法寻找合适大小的内存。并且获取堆的内容需要两次访问,第一次访问指针,第二次根据指针保存的地址访问内存,因此堆比较慢。

9. 介绍什么时候会发生栈溢出和堆溢出?

栈溢出:

  • 函数调用层次过深,每调用一次,函数的参数、局部变量等信息就压一次栈。

  • 局部静态变量体积太大。

堆溢出:

  • 动态申请空间使用之后没有释放。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 京存分布式赋能EDA应用
  • Aviator的介绍与使用以及基本原理
  • 如何选择适合医疗器械行业的ERP软件?盘谷医疗 符合验收
  • python爬虫,使用pyppeteer异步,爬取,获得指定标签内容
  • 如何在没有密码的情况下从 iPad 中删除 MDM?100% 工作
  • 【系统架构设计】测试评审方法
  • 打卡学习Python爬虫第五天|Xpath解析的使用
  • 书生大模型实战营第三期基础岛第三课——浦语提示词工程实践
  • 城乡燃气安全监管平台 打造城市安全防护网
  • JavaJSON处理工具类JSONUtils
  • python-字符串排序(赛氪OJ)
  • 视频转音频mp3软件有哪些?分享好用的转换工具
  • docker具体操作
  • 一把手告诉你联盟营销白帽电商广告借力NewsBreak头条优势
  • 队列相关内容
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • 【干货分享】SpringCloud微服务架构分布式组件如何共享session对象
  • ES6语法详解(一)
  • HTML5新特性总结
  • input实现文字超出省略号功能
  • java架构面试锦集:开源框架+并发+数据结构+大企必备面试题
  • ng6--错误信息小结(持续更新)
  • Python_网络编程
  • socket.io+express实现聊天室的思考(三)
  • Theano - 导数
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 力扣(LeetCode)22
  • 前端技术周刊 2018-12-10:前端自动化测试
  • 嵌入式文件系统
  • 容器服务kubernetes弹性伸缩高级用法
  • 深度解析利用ES6进行Promise封装总结
  • 世界上最简单的无等待算法(getAndIncrement)
  • 算法-图和图算法
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 【云吞铺子】性能抖动剖析(二)
  • 整理一些计算机基础知识!
  • # 利刃出鞘_Tomcat 核心原理解析(八)-- Tomcat 集群
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • #QT项目实战(天气预报)
  • $.ajax()参数及用法
  • $.ajax中的eval及dataType
  • (arch)linux 转换文件编码格式
  • (差分)胡桃爱原石
  • (顶刊)一个基于分类代理模型的超多目标优化算法
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (独孤九剑)--文件系统
  • (二刷)代码随想录第16天|104.二叉树的最大深度 559.n叉树的最大深度● 111.二叉树的最小深度● 222.完全二叉树的节点个数
  • (论文阅读22/100)Learning a Deep Compact Image Representation for Visual Tracking
  • (论文阅读30/100)Convolutional Pose Machines
  • (七)微服务分布式云架构spring cloud - common-service 项目构建过程
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (数据结构)顺序表的定义
  • (学习日记)2024.02.29:UCOSIII第二节
  • (一)80c52学习之旅-起始篇