(笔记)堆和栈的区别-两种不同的数据结构

堆栈其实是两种数据结构。堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。

要点:堆:顺序随意.

        栈:后进先出(Last-In/First-Out) 

堆和栈的区别

一、预备知识—程序的内存分配
一个由C/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap)— 由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
3、全局区(静态区)(static)— 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释
放。
4、文字常量区 — 常量字符串就是放在这里的,程序结束后由系统释放 。
5、程序代码区— 存放函数体的二进制代码。
二、例子程序
这是一个前辈写的,非常详细
//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);
}
分配得来的10和20字节的区域就在堆区。
strcpy(p1, "123456"); 123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。

堆和栈的理论知识

1.申请方式 
stack:
由系统自动分配。 例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间
heap:
需要程序员自己申请,并指明大小,在c中malloc函数
如p1 = (char *)malloc(10);
在C++中用new运算符
如p2 = new char[20];//(char *)malloc(10);
但是注意p1、p2本身是在栈中的。

2.申请后系统的响应

栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出,此时处理器通常会进入hardfault硬件错误中断,注:硬件错误中断通常都是由于堆栈溢出或对非法地址进行操
           作。
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给
程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系
统会自动的将多余的那部分重新放入空闲链表中。
3.申请大小的限制 
栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在 WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个
编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。注:对于处理器而言,栈与堆的大小都是可以通过修改配置文件或在编译器选项中修改
           的。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内
存。由此可见,堆获得的空间比较灵活,也比较大。
4.申请效率的比较 
栈由系统自动分配,速度较快。但程序员是无法控制的。
堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.
另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈,而是直接在进程的地址空间中保留一块内存,虽然用起来最不方便。但是速度快,也最灵活
5.堆和栈中的存储内容 
栈: 在函数调用时,第一个进栈的是主函数中函数调用后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数。注:在大多数的C编译器中,参数是由右往左入栈的,然后是函
             数中的局部变量。注意静态变量是不入栈的。
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。
6.存取效率的比较 
char s1[] = "aaaaaaaaaaaaaaa";
char *s2 = "bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在运行时刻赋值的;
而bbbbbbbbbbb是在编译时就确定的;
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
比如:
#include
void 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],cl
11: 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],al
第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据edx读取字符,显然慢了。
7.小结: 
堆和栈的区别可以用如下的比喻来看出:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

堆和栈的主要分别:

操作系统方面的堆和栈,如上面说的那些,不多说了。
还有就是数据结构方面的堆和栈,这些都是不同的概念。这里的堆实际上指的就是(满足堆性质的)优先队列的一种数据结构,第1个元素有最高的优先权;栈实际上就是满足后进先出的性质的数学或数据结构。
虽然堆栈,堆栈的说法是连起来叫,但是他们还是有很大区别的,连着叫只是由于历史的原因。

堆与栈的分布

所以堆和栈的区别:

    stack的空间由操作系统自动分配/释放,heap上的空间手动分配/释放。

    stack的空间有限,heap是很大的自由存储区。

    程序在编译期和函数分配内存都是在栈上进行,且程序运行中函数调用时参数的传递也是在栈上进行。

 

  作者: tdyizhen1314

            (现从事LED行业,专注于户外大型LED显示屏控制系统的研发,希望与大家一起交流,共同进步)

  邮箱: 495567585@qq.com  

           td.logic@hotmail.com

 

 

转载于:https://www.cnblogs.com/tdyizhen1314/archive/2011/12/29/2306617.html

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.net post提交后接收返回数据_Ajax提交表单的方式

和提交普通表单一样发送数据浏览器端代码$使用开发者工具查看请求体https://cdn.jsdelivr.net/gh/zhangfu1111/Blogimagemanager/images/springboot20200712150040.pngcontroller代码ResponseBody整个请求体是一个JSON数据浏览器端代码$使用开发者工具查看请求体![](https://cd…

javascript高程3 学习笔记(三)

执行环境 执行环境是什么? javascript的解释器每次开始执行一个函数时,都会为每个函数创建一个执行环境(execution context)。执行环境定义了变量或者函数有权访问的其他数据,决定了他们各自的行为。与执行环境相关的变…

一张纸还能上天能救命?理工男宁愿放弃NASA百万年薪,也要回家折纸?!

全世界有3.14 % 的人已经关注了爆炸吧知识一张纸能做什么?小时候,它可能默默记录着你天马行空的想象力:而到了艺术家手中,它们就会变幻成各种各样精妙绝伦的艺术品:可当一双文艺的手,遇上一颗聪明无比的“理…

【干货】单日10亿GMV的.NET5电商平台,是如何设计的?

自京东和唯品会转了Java,.NET就一直缺乏高并发电商案例,.NET5能做高并发电商吗?必须的,别停留在.NET Framework的旧印象了!这里为大家分享一家上市公司的项目案例,纯.NET5电商平台,轻松承接双11…

如何发送html email,如何发送HTML电子邮件?

我已经使用JMS在Web应用程序中成功发送了电子邮件,但是结果仅以纯文本显示。我希望内容能够显示html。我该怎么做?这大致就是我所拥有的:Message msg new MimeMessage(mailSession);try{msg.setSubject("Test Notification");msg.…

通过 Lotus Domino Java 代理消费 Web 服务

Web 服务是一种允许两台或更多的计算机在网络中交互的系统设计。这种服务的主要优点是,它是在多台不同操作系统的计算机和应用服务器之间发送对象的标准解决方法。例如,我们的公司使用 Web 服务从一台运行 Microsoft .NET Framework 的计算机向基于 IBM …

goahead如何使用cgi服务_QQ如何设置使用代理服务器?

很多人可能会问了,QQ上可以设置代理服务器吗?答案是可以的。今天就为大家详细介绍一下,如何在QQ上设置代理服务器的。1、双击QQ图标,打开QQ登录界面,我们就可以看到界面右上角有一个“设置”按钮。QQ如何设置使用代理服务器12、点…

自动布局AutoLayout

http://www.th7.cn/Program/IOS/201410/304252.shtml转载于:https://www.cnblogs.com/runer/p/4430675.html

android listview添加数据_Android面经分享,失业两个月,五一节前拿到offer

秦子帅明确目标,每天进步一点点.....作者 | 天天有道地址 | juejin.im/post/5eb01866f265da7b9c24562c基本介绍今天介绍一位朋友的经历:从3月初开始复习,准备面试题。复习的资料主要为《Android开发艺术探索》和jsonchao的博客,…

Dapr + .NET 实战(四)发布和订阅

什么是发布-订阅发布订阅是一种众所周知并被广泛使用的消息传送模式,常用在微服务架构的服务间通信,高并发削峰等情况。但是不同的消息中间件之间存在细微的差异,项目使用不同的产品需要实现不同的实现类,虽然是明智的决策&#x…

词性分法程序

http://tieba.baidu.com/p/1180650771?pid13814874186&cid0#13814874186 给你个函数看看,分析下有什么用 句列表指针 存储的是一句话的数据,其中已经分好词,并知道每个词的词性.周春海(专有名词) 是(动词) 周依言(专有名词) 的(的词) 爸爸(抽象名词) .(句号词)程序里的词性…

计算机信息处理教案,冀教版七年级信息技术第二课计算机--信息处理工具 教案...

ID:10796280分类:江苏,2019资源大小:22KB资料简介:《第二课 计算机——信息处理工具》教学设计教 者:课时1教学内容:第二课 计算机——信息处理工具教学目标:1知识目标:学生应了解计算机的工作原理&#xf…

这些数学趣图,数学老师看了后会怎么想?

全世界有3.14 % 的人已经关注了爆炸吧知识这个扣分不?我的人生98%的时间都是无比正确的数学与我不能言语的关系最深情的告白限速是......当我完成数学作业后....维生素C的来历高数课堂恩..... 来拜师了啊, 好好学习. 为师给你命名: 阿尔法狗.这个是驻点, 这是最值, 这些机器学…

COM 组件设计与应用(六)

一、前言  1、与 《COM 组件设计与应用(五)》的内容基本一致。但本回讲解的是在 vc.net 2003 下的使用方法,即使你不再使用vc6.0,也请和上一回的内容,参照比对。   2、这第一个组件,除了所有 COM 组件必须的 IUnknown 接口外&…

为什么不可以使用哈曼顿距离_请对比下欧式距离和曼哈顿距离的差别

●今日面试题分享●在k-means或kNN,我们常用欧氏距离来计算最近的邻居之间的距离,有时也用曼哈顿距离,请对比下这两种距离的差别解析:欧氏距离,最常见的两点之间或多点之间的距离表示法,又称之为欧几里得度…

dmidecode常用的查询

1、查看内存槽数、那个槽位插了内存,大小是多少dmidecode|grep -P -A5 "Memory\sDevice"|grep Size|grep -vRange2、查看最大支持内存数dmidecode|grep -P \Maximum\sCapacity\3、查看槽位上内存的速率,没插就是unknown。dmidecode|grep -A16 …

python 柱状图 间距_专题第18篇:Python 绘图入门

我的施工之路1我的施工计划2数字专题3字符串专题4列表专题5流程控制专题6编程风格专题7函数使用8面向对象编程(上篇)9面向对象编程(下篇)10十大数据结构11包和模块使用总结12Python正则专题总结13设计模式14Python时间模块总结15 Python 装饰器16 Python 迭代器17 Python 生成器…

WPF实现截屏(仿微信)

WPF开发者QQ群: 340500857 | 微信群 -> 进入公众号主页 加入组织欢迎转发、分享、点赞、在看,谢谢~。 前言有小伙伴需要在软件反馈窗体增加截图功能需求,所以今天来实现一个仿微信的截图。01—效果预览效果预览(更多效果请下…

我妈要把闺蜜介绍给我当女朋友......

1 反正手没闲着啊▼2 这...这女孩子不会是您跳广场舞认识的吧?▼3 这就是生活▼4 有画面感了▼5 这种运动会想想就觉得很好看▼6 电脑屏幕不亮手机玩起来不够舒服▼7 这种脱衣方式可真是太酷啦!▼你点的每个赞,我都认真当成了喜欢

用回溯法找出n个自然数中取r个数的全排列

回溯法也称为试探法,该方法首先暂时放弃关于问题规模大小的限制,并将问题的候选解按某种顺序逐一枚举和检验。在回溯法中,放弃当前候选解,寻找下一个候选解的过程称为回溯。本实例是用回溯法输出n个自然数中以r个数全排列。代码如…