1、从C/C++的内存分配上来说,堆(heap)和栈(stack)属于内存空间的一段区域。

如图:

一个程序在内存上由BSS段、data段、text段三个组成的。在没有调入内存前,可执行程序分为代码段、数据区和未初始化数据区三部分。

BSS段:(Block Started by Symbol)通常是指用来存放程序中未初始化的全局变量的一块内存区域,属于静态内存分配。BSS段的内容并不存放在磁盘上的程序文件中。原因是内核在程序开始运行前将它们设置为0,需要存放在程序文件中的只有正文段和初始化数据段。text段和data段在编译时已经分配了空间,而BSS段并不占用可执行文件的大小,它是由链接器来获取内存的。

数据段:(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域,属于静态内存分配。总结为:初始化的全局变量和静态变量在已初始化区域,未初始化的全局变量和静态变量在BSS区。

代码段:(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。该区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

堆(heap):用于动态分配内存,位于BSS和栈中间的地址区域,由程序员申请分配和释放。堆是从低地址位向高地址位增长,采用链式存储结构。频繁的malloc/free造成内存空间的不连续,会产生碎片。当申请堆空间时库函数是按照一定的算法搜索可用的足够大的空间,因此堆的效率比栈要低的多。注:与数据结构中的堆不是一个概念,但堆的分配方式类似于链表。

栈(stack): 由编译器自动释放,存放函数的参数值、局部变量等。每当一个函数被调用时,该函数的返回类型和一些调用的信息被存放到栈中,这个被调用的函数再为它的自动变量和临时变量在栈上分配空间。每调用一个函数一个新的栈就会被使用。栈区是从高地址位向低地址位增长的,是一块连续的内存区域,最大容量是由系统预先定义好的,申请的栈空间超过这个界限时会提示溢出。

2、区别

1.申请方式
堆是由程序员自己申请并指明大小,在c中malloc函数 如p1 = (char *)malloc(10);
栈由系统自动分配,如声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间

2.申请后系统的响应
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会 遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内 存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大 小,系统会自动的将多余的那部分重新放入空闲链表中。

3.申请大小的限制
栈:在Windows下,栈是向低地址扩展的数据结 构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是 一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。

堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

4.申请效率的比较:
栈由系统自动分配,速度较快。但程序员是无法控制的。
堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。

堆和栈是什么?有哪些区别?相关推荐

  1. java堆和栈 常量池_GitHub - han-guang-xue/difference-of-stack-heap-pool: Java中堆、栈和常量池的区别...

    Java中堆.栈和常量池的区别 栈 堆 常量池的概念 首先我们先了解一下概念,Java把内存分成两种,一种叫做栈内存,一种叫做堆内存. 栈内存 存放基本类型的变量数据和对象类型的引用(请注意存放的是引 ...

  2. Java中堆、栈和常量池的区别

    转自: https://blog.csdn.net/qq_45121279/article/details/91446764

  3. C/C++ 全局变量和局部变量在内存里的区别?堆和栈

    一.预备知识-程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分  1.栈区(stack)- 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈 ...

  4. 堆和栈的区别(面试经验总结)

    C++中,内存分为5个区:堆.栈.自由存储区.全局/静态存储区和常量存储区. 栈:是由编译器在需要时自动分配,不需要时自动清除的变量存储区.通常存放局部变量.函数参数等. 堆:是由new分配的内存块, ...

  5. “堆”,栈,堆栈,队列,它们的区别?

    2019独角兽企业重金招聘Python工程师标准>>> 什么是"堆","栈","堆栈","队列",它们 ...

  6. 堆和栈的区别 (转贴)

    非本人作也!因非常经典,所以收归旗下,与众人阅之!原作者不祥! 堆和栈的区别 一.预备知识-程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)- 由编译器自动 ...

  7. mysql中堆和栈_堆和栈的区别

    在说堆和栈之前,我们先说一下JVM(虚拟机)内存的划分: Java程序在运行时都要开辟空间,任何软件在运行时都要在内存中开辟空间,Java虚拟机运行时也是要开辟空间的.JVM运行时在内存中开辟一片内存 ...

  8. 堆(heap)与栈(stack)的区别(一)

    堆区(heap):一般由程序员分配和释放,若程序员不释放,程序结束时可能由操作系统回收,但它与数据结构中的堆不是一回事,分配方式类似于链表. 栈(stack):由编译器自动分配和释放,存函数的参数值, ...

  9. (009) java后台开发之堆和栈的区别

    转自:https://course.tianmaying.com/java-basic+object-usage# 堆和栈的区别 堆和栈都是Java中常用的存储结构,都是内存中存放数据的地方: 1.在 ...

  10. 进程、线程、堆、栈的理解和区别!

    一:进程和线程的定义 (1)进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.  (2)线程是进程的一个实体,是CPU调度和分派的基本单位,它是 ...

最新文章

  1. 关键任务应用程序依赖于故障保护存储器
  2. 4、通过uiautomatorviewer实现appium元素定位
  3. 上交三月月赛[SJTU] 1105 path
  4. 第五章spring框架基础
  5. 《事实:用数据思考,避免情绪化决策》笔记
  6. VS.左侧_蓝黄绿_竖线
  7. 两分钟看懂CPU生产过程
  8. C#遍历DataSet数据的几种方法总结
  9. 标签 'http' 已声明。标签名称在批查询或存储过程内部必须唯一。
  10. 【HDU 5033】【经典单调栈问题】Building
  11. 网刻工具大全:四款软件优缺评析(转)
  12. 计算机视觉(北邮鲁鹏)--边缘提取
  13. Axure 点图片外区域即隐藏_多年后终迎换代,新奔腾B70——颜值即是正义!_搜狐汽车...
  14. 国产开源「文本-视频生成」模型!免费在线体验,一键实现视频生成自由
  15. GitHub 颜值这么高的播放器,太爱了!
  16. spring cloud eureka 样式没有了,wro.css wro.js 404
  17. Quartz定时调度
  18. 直充卡券话费接口API源码分享
  19. CIR,CBS,EBS,PIR,PBS令牌桶概述
  20. 晚上睡不好怎么办?试试这几个睡前助眠小妙招

热门文章

  1. python提取Excel某几列数据
  2. 计算机PPT教材教法,小语教材教法讲义课件_电脑基础知识_it计算机_专业资料.ppt...
  3. 图像处理之预处理方法
  4. spring Boot Configuration Annotation Processor not fount in classpath
  5. android短信和彩信探秘threads
  6. 如何解决报错500的问题
  7. 阿里云FaaS舜天平台:执FPGA异构计算之牛耳
  8. Vim中如何全选复制粘贴
  9. java audit模块实现_Linux安全审计功能的实现——audit详解
  10. git之删除仓库文件