C++ 堆 和 堆 分析
【摘要】
堆和栈,即是数据结构,又是分配存储空间的不同方式。在数据结构上。堆是树型层次结构,结点按keyword次序排列,经常使用的堆为二叉堆;栈是一种先进后出的数据结构。在内存分配上的堆和栈,首要差别在于申请方式不同。其次在存取速度、存储空间的大小、存储内容(一定要记住,栈中是第一条可运行语句地址。然后是各个參数。堆中头部是堆的大小描写叙述。之后有程序猿自己安排)、内存中的相对位置和系统相应的响应上都各有自己差别。在C语言 的学习过程中,堆和栈即是基础也是重点。
【正文】
堆栈是一个非常模糊的概念,堆栈:一种数据结构?一个在程序执行时用于存放的地方?这可能是非常多刚開始学习的人的认识,由于,我以前就是这么想的和汇编语言中的堆栈一词混为一谈。
数据结构中的堆栈
实际上堆栈是两种数据结构:堆和栈。堆和栈都是一种数据项按序排列的数据结构。
栈是一种具有后进先出性质的数据结构,也就是说后存放的先取,先存放的后取。 这就如同我们要取出放在箱子里面底下的东西(放入的比較早的物体)。我们首先要移开压在它上面的物体(放入的比較晚的物体)。而堆就不同了,堆是一种经过排序的树形数据结构。每一个结点都有一个值。通常我们所说的堆的数据结构。是指二叉堆。 堆的特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆。因为堆的这个特性。经常使用来实现优先队列,堆的存取是随意。 这就如同我们在图书馆的书架上取书。尽管书的摆放是有顺序的,可是我们想取随意一本时不必像栈一样,先取出前面全部的书,书架这样的机制不同于箱子。我们能够直接取出我们想要的书。
可是,重点并不在数据结构的堆和栈,之所以要说数据结构的堆和栈是为了和堆区和栈区差别开来。内存分配中的堆栈
以下就说说C语言程序内存分配中的堆和栈,这里有必要把内存分配也提一下。大家不要嫌我啰嗦。普通情况下程序存放在Rom(仅仅读内存,比方硬盘)或Flash中,执行时须要拷到RAM(随机存储器RAM)中执行。RAM会分别存储不同的信息,例如以下图所看到的:
内存中的栈区处于相对较高的地址。栈地址是向下增长的,栈中分配局部变量空间,堆区处于相对较低的地址。是向上增长的用于分配程序猿申请的内存空间。 另外还有静态区是分配静态变量,全局变量空间的。仅仅读区是分配常量和程序代码空间的。以及其它一些分区。
来看一个网上非常流行的经典样例:
main.cpp
int a = 0; //全局初始化区
char *p1; //全局未初始化区
main()
{
int b; //栈
char s[] = "abc"; //栈
char *p2; //栈
char *p3 = "123456"; //123456\0在常量区,p3在栈上。
static int c =0。 //全局(静态)初始化区
p1 = (char *)malloc(10); //堆
p2 = (char *)malloc(20); //堆
}
内存分配中堆和栈的差别与联系
1. 申请方式不同(首要差别)
栈(英文名称是stack)是系统自己主动分配空间的。比如我们定义一个 char a;系统会自己主动在栈上为其开辟空间。堆(英文名称是heap)是程序猿依据须要自己申请的空间。比如malloc(10);开辟十个字节的空间。因为栈上的空间是自己主动分配自己主动回收的,所以栈上的数据的生存周期仅仅是在函数的执行过程中,执行后就释放掉,不能够再訪问。而堆上的数据仅仅要程序猿不释放空间,就一直能够訪问到,只是缺点是一旦忘记释放会造成内存泄露。
2. 申请后系统的响应
栈:仅仅要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。堆:首先应该知道操作系统有一个记录空暇内存地址的链表,当系统收到程序的申请时。会遍历该链表。寻找第一个空间大于所申请空间的堆结点,然后将该结点从空暇结点链表中删除,并将该结点的空间分配给程序。另外,对于大多数系统。会在这块内存空间中的首地址处记录本次分配的大小。这样,代码中的 delete语句才干正确的释放本内存空间。另外,因为找到的堆结点的大小不一定正好等于申请的大小。系统会自己主动的将多余的那部分又一次放入空暇链表中。也就是说堆会在申请后还要做一些兴许的工作这就会引出申请效率的问题
3. 申请效率的比較
栈由系统自己主动分配,速度较快。但程序猿是无法控制的。堆是由new分配的内存。一般速度比較慢,并且easy产生内存碎片,只是用起来最方便。
4. 堆和栈中的存储内容
栈: 在函数调用时,第一个进栈的是主函数中函数调用后的下一条指令(函数调用语句的下一条可执行语句)的地址。然后是函数的各个參数。 在大多数的C编译器中,參数是由右往左入栈的。然后是函数中的局部变量。注意静态变量是不入栈的。 当本次函数调用结束后。局部变量先出栈,然后是參数,最后栈顶指针指向最開始存的地址,也就是主函数中的下一条指令。程序由该点继续执行。堆:通常是在堆的头部用一个字节存放堆的大小。堆中的详细内容有程序猿安排。
5. 存取效率的比較
char s1[] = "aaaaaaaaaaaaaaa";char *s2 = "bbbbbbbbbbbbbbbbb";aaaaaaaaaaa是在执行时刻赋值的。而bbbbbbbbbbb是在编译时就确定的;
可是,在以后的存取中。在栈上的数组比指针所指向的字符串(比如堆)快。
【例】#includevoid main(){char a = 1;char c[] = "1234567890";char *p ="1234567890";a = c[1];a = p[1];return;}【相应的汇编代码 】10: a = c[1];00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]0040106A 88 4D FC mov byte ptr [ebp-4],cl11: a = p[1];0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]00401070 8A 42 01 mov al,byte ptr [edx+1]00401073 88 45 FC mov byte ptr [ebp-4],al6. 申请大小的限制
栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在 WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),假设申请的空间超过栈的剩余空间时。将提示overflow。 因此,能从栈获得的空间较小。堆:堆是向高地址扩展的数据结构,是不连续的内存区域。 这是因为系统是用链表来存储的空暇内存地址的。自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见。堆获得的空间比較灵活。也比較大。
最后引用一位前辈的比喻来结束堆和栈的差别,使用栈就象我们去饭馆里吃饭,仅仅管点菜(发出申请)、付钱、和吃(使用)。吃饱了就走。不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的优点是快捷,可是自由度小。 使用堆就象是自己动手做喜欢吃的菜肴。比較麻烦,可是比較符合自己的口味。并且自由度大。比喻非常形象,说的非常通俗易懂。我不知道,如果你是一个小的收获。
版权声明:本文博主原创文章,博客,未经同意不得转载。
C++ 堆 和 堆 分析的更多相关文章
- 使用 Eclipse Memory Analyzer 进行堆转储文件分析
Eclipse Memory Analyzer(MAT)是著名的跨平台集成开发环境 Eclipse Galileo 版本的 33 个组成项目中之一,它是一个功能丰富的 JAVA 堆转储文件分析工具,可 ...
- 《深入理解Java虚拟机》(六)堆内存使用分析,垃圾收集器 GC 日志解读
堆内存使用分析,GC 日志解读 重要的东东 在Java中,对象实例都是在堆上创建.一些类信息,常量,静态变量等存储在方法区.堆和方法区都是线程共享的. GC机制是由JVM提供,用来清理需要清除的对象, ...
- mat 使用 分析 oom 使用 Eclipse Memory Analyzer 进行堆转储文件分析
概述 对于大型 JAVA 应用程序来说,再精细的测试也难以堵住所有的漏洞,即便我们在测试阶段进行了大量卓有成效的工作,很多问题还是会在生产环境下暴露出来,并且很难在测试环境中进行重现.JVM 能够记录 ...
- [Android Memory] 使用 Eclipse Memory Analyzer 进行堆转储文件分析
转载地址:http://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-ma/index.html Eclipse Memory Analyzer ...
- <JVM下篇:性能监控与调优篇>补充:浅堆深堆与内存泄露
笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...
- 【ZZ】堆和堆的应用:堆排序和优先队列
堆和堆的应用:堆排序和优先队列 https://mp.weixin.qq.com/s/dM8IHEN95IvzQaUKH5zVXw 堆和堆的应用:堆排序和优先队列 2018-02-27 算法与数据结构 ...
- SQL0973N在 "<堆名>" 堆中没有足够的存储器可用来处理语句
SQL0973N在 "<堆名>" 堆中没有足够的存储器可用来处理语句. 解释: 已使用此堆的所有可用内存.不能处理该语句. 用户响应: 接收到此消息(SQLCODE)后 ...
- bzoj 1577: [Usaco2009 Feb]庙会捷运Fair Shuttle——小根堆+大根堆+贪心
Description 公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N.K(1<=K<=50000)群奶牛希望搭乘这辆公交车.第i群牛一共有Mi(1& ...
- 0day堆(1)堆的管理策略
基本概念 堆块:堆区内存的基本单位 包括两个部分:块首,块身 块首:标识这个堆块自身的信息:如大小,是否被占用等 块身:分配给用户使用的数据区 堆表:一般位于堆区的起始位置,用于索引堆区所有堆块的信息 ...
随机推荐
- 安卓---项目中插入百度地图sdk
百度地图 应用里面 自带地图 搜房网 下载百度地图的sdk 熟悉api 注冊百度开发人员的账号 2.12 仅仅要有一个ak就能够 高版本号须要提供应用程序的包名和签名返回开发人员的序列号 使用百度地图 ...
- php查找字符串是否存在
strstr //搜索字符串在另一字符串中的首次出现(对大小写敏感) //该函数返回字符串的其余部分(从匹配点).如未找到则返回 false stristr //查找字符串在另一字符串中第一次出现的位 ...
- FZUOJ Problem 2178 礼品配送
Problem 2178 礼物分配 题目链接: Click Here~ Problem Description 在双胞胎兄弟Eric与R.W的生日会上,他们共收到了N个礼物,生日过后他们决定分配这N个 ...
- 面向服务的体系架构SOA
面向服务的体系架构SOA 序言 在.Net的世界中,一提及SOA,大家想到的应该是Web Service,WCF,还有人或许也会在.NET MVC中的Web API上做上标记,然后泛泛其谈! 的确,微 ...
- WPF之Binding深入探讨--Darren
1,Data Binding在WPF中的地位 程序的本质是数据+算法.数据会在存储.逻辑和界面三层之间流通,所以站在数据的角度上来看,这三层都很重要.但算法在3层中的分布是不均匀的,对于一个3层结构的 ...
- spring 重定向以及转发 乱码问题解决
1.spring 转发 request.setAttribute("id", id); request.setAttribute("name",name); r ...
- 【牛腩新闻公布系统】WebForms UnobtrusiveValidationMode 须要“jquery”ScriptResourceMapping。
问题: WebForms UnobtrusiveValidationMode须要"jquery"ScriptResourceMapping. 请加入一个名jquery ...
- HBuilder之初体验
听闻HTML5定稿了,所以特意去了解了下.文章有提到HTML5的一款IDE(HBuilder,貌似出来好久了,孤陋寡闻....),于是来到官网http://dcloud.io/ ,被演示图震惊了!果然 ...
- 输出无名空数组---精android、IOS App应用服务程序开发
直接输出 [] 示例文件_samples/app/array_null.json在轻开平台的_samples/app/文件夹下 太Easy.无法写出很多其它的内容,大家还是自己试试吧! ! ! 相关资 ...
- OOP思想
OOP思想 读者朋友们大家好,我们今天这一讲就接着前面的封装继续讲解,今天就是在前面内容上面的升级,OOP思想中的继承,我们就先来解释一下继承到底是什么意思,我们在什么地方会用到继续. 继承就是,后代 ...