c语言中栈堆,C语言中堆和栈的区别

二.堆和栈的区别

1.申请方式

(1)栈(satck):由系统自动分配。例如,声明在函数中一个局部变量int b;系统自动在栈中为b开辟空间。

(2)堆(heap):需程序员自己申请(调用malloc,realloc,calloc),并指明大小,并由程序员进行释放。容易产生memory leak.

eg:char  p;

p = (char *)malloc(sizeof(char));

但是,p本身是在栈中。

2.申请大小的限制

(1)栈:在windows下栈是向底地址扩展的数据结构,是一块连续的内存区域(它的生长方向与内存的生长方向相反)。栈的大小是固定的。如果申请的空间超过栈的剩余空间时,将提示overflow。

(2)堆:堆是高地址扩展的数据结构(它的生长方向与内存的生长方向相同),是不连续的内存区域。这是由于系统使用链表来存储空闲内存地址的,自然是不连续的,而链表的遍历方向是由底地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。

3.系统响应:

(1)栈:只要栈的空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。

(2)堆:首先应该知道操作系统有一个记录空闲内存地址的链表,但系统收到程序的申

请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这

块内存空间中的首地址处记录本次分配的大小,这样,代码中的free语句才能正确的释放本内存空间。另外,找到的堆结点的大小不一定正好等于申请的大小,

系统会自动的将多余的那部分重新放入空闲链表中。

说明:对于堆来讲,对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,

4.申请效率

(1)栈由系统自动分配,速度快。但程序员是无法控制的

(2)堆是由malloc分配的内存,一般速度比较慢,而且容易产生碎片,不过用起来最方便。

5.堆和栈中的存储内容

(1)栈:在函数调用时,第一个进栈的主函数中后的下一条语句的地址,然后是函数的各个参数,参数是从右往左入栈的,然后是函数中的局部变量。注:静态变量是不入栈的。

当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续执行。

(2)堆:一般是在堆的头部用一个字节存放堆的大小。

6.存取效率

(1)堆:char *s1=”hellow tigerjibo”;是在编译是就确定的

(2)栈:char s1[]=”hellow tigerjibo”;是在运行时赋值的;用数组比用指针速度更快一些,指针在底层汇编中需要用edx寄存器中转一下,而数组在栈上读取。

补充:

栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈

的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按

照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可

能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。

7.分配方式:

(1)堆都是动态分配的,没有静态分配的堆。

(2)栈有两种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的。它的动态分配是由编译器进行释放,无需手工实现。

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

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

相关文章

webview部分安卓机中文乱码

在开发过程中需要加载html片断,发现安卓机上是乱码,这可郁闷了,官方文档也没有这方面的介绍,还好度娘还好的,记录一下解决方案: 其实很简单,只在source对象中添一个属性baseUrl为空就可以解决&a…

MongoDB存储基础教程

一、MongoDB简介 1. mangodb是一种基于分布式、文件存储的非关系型数据库   2. C写的,性能高   3. 为web应用提供可扩展的高性能数据存储解决方案   4. 所支持的格式是json格式 二、MongoDB三元素&和关系型数据库的区别 三元素:数据库 集合(类…

Tomcat的带有守护程序和关闭挂钩的正常关闭

我的最后两个博客讨论了长时间轮询和Spring的DeferredResult技术,并且为了展示这些概念,我将我的Producer Consumer项目中的代码添加到了Web应用程序中。 尽管该代码演示了博客所提出的观点,但其逻辑上确实包含大量漏洞。 除了在实际的应用程…

java 递归从子节点删除父节点_LeetCode450. 删除二叉搜索树中的节点

删除一个二叉搜索树中的节点,需要进行情况的分类讨论,看一下将这个节点删除之后是否需要对二叉搜索树进行调整(为了保持树的连接和维持二叉搜索树的性质)。(1)如果删除的是一个叶子节点,那问题不…

1. [文件]- 文件类型,文件open模式

1.文件类型:文本文件和二进制文件 硬盘中的文件保存为01010101格式,一般读取文件是把文件从硬盘中读取到内存中。 文本文件需要进行格式转换才能读取出来。二进制文件一般用于传输二进制文件:视频图片 2.文件打开模式 几种不同的读取和遍历文…

c语言鼠标移动响应,CSS鼠标响应事件经过、移动、点击示例介绍

几种鼠标触发CSS事件。说明:onMouseDown 按下鼠标时触发onMouseOver 鼠标经过时触发onMouseUp 按下鼠标松开鼠标时触发onMouseOut 鼠标移出时触发onMouseMove 鼠标移动时触CSS 鼠标响应事件.Off{ background-color: #00FF66; padding:100px;}.up{background-color: …

node安装node-sass失败,配置淘宝源

node-sass 安装失败的原因是因为无法下载 .node 文件,解决办法就很简单了,就是我们把文件下载路径复制一份到浏览器里,然后使用浏览器下载文件就可以了。 具体方法 1.从node命令行中复制 .node文件下载链接并在浏览器打开下载文件https:/…

django 日志配置

django 日志配置 LOGGING { version: 1, disable_existing_loggers: False, formatters: { standard: { format: %(levelname)s %(asctime)s %(pathname)s %(filename)s %(funcName)s %(lineno)d: %(message)s }, # INFO 2016-09-03 16:25:20,067 /home/ubuntu/mysite/views.p…

带有Atomikos示例的Tomcat中的Spring JTA多个资源事务

在本教程中,我们将向您展示如何使用Atomikos Transaction Manager在Tomcat服务器中实现JTA多个资源事务。 Atomicos事务管理器为分布式事务提供支持。 这些是多阶段事务,通常使用多个数据库,必须以协调的方式提交。 分布式事务由XA standard描…

mac vs 返回上一步_mac电脑打不开应用程序的解决方法

mac电脑跟windows电脑一样,经常会出现打不开应用程序的情况,并且提示“因为它来自身份不明的开发者”,也不知道哪里出现问题?由于MAC系统与windows界面不一样,很多小编不懂怎么操作?为此,小编给…

C#DES加密

记录一下 DES加密 public static string DESEncrypt(string Data, string key){return DESEncrypt(Data, key, "utf-8");}/// <summary>/// DES加密算法/// </summary>/// <param name"Data">加密明文</param>/// <param name&…

c语言链表有没有哨兵的区别,链表中的哨兵(sentinel)

哨兵节点广泛应用于树和链表中&#xff0c;如伪头、伪尾、标记等&#xff0c;它们是纯功能的&#xff0c;通常不保存任何数据&#xff0c;其主要目的是使链表标准化&#xff0c;如使链表永不为空、永不无头、简化插入和删除。问题&#xff1a;删除链表中等于给定值val的所有节点…

jquery 获取标签名(tagName)

如果是为了取到tagName后再进行判断&#xff0c;那直接用下面的代码会更方便&#xff1a; $(element).is(input) 如果是要取到标签用作到别的地方&#xff0c;可以使用一下代码&#xff1a; $(element)[0].tagName或&#xff1a;$(element).get(0).tagName 转载请注明&#xff…

番石榴条纹类的细粒度并发

这篇文章将介绍如何使用Guava中的Striped类来实现更细粒度的并发。 ConcurrentHashMap使用条带化锁定方法来增加并发性&#xff0c;并且Striped类通过赋予我们具有条带化Locks &#xff0c; ReadWriteLocks和Semaphores的能力来扩展此主体。 当访问对象或数据结构&#xff08;例…

iOS-----------关于组件化

打一个比较形象的比喻&#xff0c;把APP比作我们的人体&#xff0c;把胳膊、大腿、心、肝、肺这些人体器官比作组件&#xff0c;各个器官分别负责他们各自的功能&#xff0c;但是他们之间也有主次之分&#xff0c;试想我们的胳膊、大腿等是不能独立完成某个任务的&#xff0c;必…

scrapy 安装

直接命令pip install scrapy安装&#xff0c;提示失败 Failed building wheel for Twisted... Microsoft Visual C 14.0 is required...等等 网上搜索一大摞windows下安装scrapy的资料&#xff0c;实践后终于大功告成&#xff0c;现分享出来 1.首先下载scrapy的whl包&#xff1…

leetcode 罗马数字转整数

罗马数字包含以下七种字符&#xff1a;I&#xff0c;V&#xff0c;X&#xff0c;L&#xff0c;C&#xff0c;D 和M。 字符数值I1V5X10L50C100D500M1000例如&#xff0c; 罗马数字 2 写做II &#xff0c;即为两个并列的 1。12 写做XII &#xff0c;即为 X II 。 27 写做 XXVII, …

android 自定义switch控件,Android中switch自定义样式

android 原生开关按钮控件 Switch 提供样式自定义方式&#xff0c;可供我们修改为适合我们开发使用的样式控件&#xff0c;自定义样式过程如下:自定义switch切换drawable新建swith_thumb.xml文件自定义switch轨道drawable新建switch_track.xmln文件,轨迹如果在选中与否过程并没…

具有瞬态属性的视图对象的钝化和激活

在应用程序模块的钝化/激活周期内&#xff0c;框架也会钝化并激活视图对象。 通常&#xff0c;框架保存有关VO状态&#xff0c;当前行&#xff0c;绑定变量值等的信息。 但是没有数据。 激活视图对象后&#xff0c;将重新执行VO的查询&#xff0c;并重新获取数据。 在大多数情况…

jsonobject修改key的值_JSON字符串操作移除空串更改key/value的介绍

对于JSON字符串的操作。移除键值、添加属性。//删除JSON对象value值var json[.....];delete(json[key]);或者delete(json.key);//添加对象objectjson.objectvalue;或者json[object]value;如果数据是查询数据库得到的&#xff0c;那么可能会存在空值&#xff0c;for循环JSON数据…