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

嵌入式——什么是堆、什么是栈

嵌入式

文章目录

  • 嵌入式
  • 一、什么是堆
  • 二、什么是栈
  • 总结


堆(Heap)和栈(Stack)是计算机内存中两种不同的数据存储方式。

一、什么是堆

(1)堆是一种内存管理方式,其内存空间不是连续的,而是杂乱无章的,通过指针来定位数据的存储位置。堆用于动态分配内存,可以根据需要动态地分配和释放内存。堆的大小通常受到计算机系统中物理内存和虚拟内存的限制。其特点就是自由(随时申请、释放、大小块随意)。
(2)堆内存是操作系统划分给堆管理器(操作系统的一段代码,属于操作系统内存管理单元)来管理的,然后向使用者(用户进程)提供API(malloc和free)来使用堆内存。
(3)什么时候需要使用堆内存?需要内存容量比较大时、需要反复使用及释放时,很多数据结构(譬如链表)的使用都需要使用堆内存。
2.堆内存管理的特点
(1)容量不限(常规需求都能满足)。
(2)申请及释放都需要手动进行,若使用完后没有释放则会造成内存泄漏,内存泄漏的堆积会导致内存溢出甚至系统崩溃。
3.C语言操作堆内存的接口
(1)堆内存申请时有三个功能类似的函数:malloc、calloc、realloc。

void *malloc(size_t size);              // 申请指定大小的内存
void *calloc(size_t nmemb, size_t size);  // 申请nmemb个内存单元,每个size字节
void *realloc(void *ptr, size_t size);     // 改变已经申请的空间的大小

(2)堆内存释放最简单,直接调用free函数即可。

void free(void *ptr);

(3)代码示例:
// 譬如要申请10个int元素的内存

malloc(40);
calloc(10, 4);

(4)C语言定义数组时必须给出数组元素个数,且无法再修改。而在Java等高级语言中,则可以修改数组大小,其原理是重新创建一个新的数组,然后释放掉原数组。realloc的实现原理也类似。

二、什么是栈

1.什么是栈?
(1)栈是一种数据结构,遵循后进先出(Last In, First Out,LIFO)的原则。
栈用于存储函数调用的局部变量、函数参数、函数返回地址以及临时数据。栈的大小是有限制的,通常由操作系统预先分配好。栈的分配和释放是由编译器自动管理的。当进入一个新的函数作用域时,局部变量和函数参数会被压入栈中;当函数退出作用域时,栈会自动弹出这些数据,以便为下一个函数调用做准备。

void func1() {int x = 1; // x 被压入栈中// ...
} // x 从栈中弹出

2.栈管理内存的特点(小内存、自动化)
(1)先进后出(FILO),而队列是先进先出(FIFO)。
(2)栈的特点是入口即出口,只有一个口,另一个口是堵死的,所以是先进后出。而队列的特点是入口和出口都有,必须从入口进去,从出口出来,所以是先进先出。
3.栈的应用举例:局部变量
(1)C语言中的局部变量是用栈来实现的,定义局部变量时,对应操作是入栈(自动化);函数退出局部变量注销的时候,对应的操作是出栈(自动化)。
(2)栈的优点:方便,分配和回收都不用程序员自己操作,C语言自动完成。
(3)定义局部变量但未初始化,值是随机的,为什么?
因为栈是反复使用的,并且每次使用完之后没有清零。
4.栈的优势和劣势
(1)优势:自动化,不用程序员手动操作内存。
(2)劣势:首先,栈是有大小的,所以栈内存大小不好设置。所以太小怕溢出,太大怕浪费内存(与数组类似)。其次,栈溢出的危害很大,一定要避免。所以我们在C语言中定义局部变量时不能定义太多或者太大(譬如不能定义int a[10000];使用递归来解决问题时一定要注意递归收敛)。

总结

区别和联系:

1.存储方式:栈是一种线性的存储结构,而堆是一种树状的存储结构。
分配和释放:栈的分配和释放是由编译器自动管理的,而堆需要手动分配和释放。
2.空间大小:栈的大小通常是固定的,由操作系统预先分配,而堆的大小受到物理内存和虚拟内存的限制。
3.数据生存周期:栈中的数据生命周期与其所在函数的执行周期相关联,函数执行完毕时,栈中的数据会被自动释放;而堆中的数据可以在程序的任意阶段使用,并且需要手动释放以避免内存泄漏。

总的来说,栈主要用于存储函数调用相关的数据,而堆则用于动态分配内存以存储动态数据。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【Spring Boot 3】【Web】国际化
  • EasyCVR视频汇聚平台:巧妙解决WebRTC无法播放H.265视频的难题
  • 透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路
  • SOMEIP_ETS_088: SD_Answer_multiple_subscribes_together
  • DML、DQL、DCL的基础介绍
  • 【Java】ApiPost请求返回 `406` 状态码(jackson)
  • 解决linux云服务器ping不通另一台linux云服务器的问题
  • IP 协议详解
  • flutter之常用数据类型
  • 力扣704:二分查找
  • Ruby 多线程
  • Django+Vue家居全屋定制系统的设计与实现
  • 某云彩SRM2.0任意文件下载漏洞
  • OpenGL知识点记录
  • 使用 GZCTF 结合 GitHub 仓库搭建独立容器与动态 Flag 的 CTF 靶场+基于 Docker 的 Web 出题与部署+容器权限控制
  • [笔记] php常见简单功能及函数
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • Docker: 容器互访的三种方式
  • Java,console输出实时的转向GUI textbox
  • JAVA_NIO系列——Channel和Buffer详解
  • Sequelize 中文文档 v4 - Getting started - 入门
  • use Google search engine
  • vue2.0项目引入element-ui
  • vue-cli在webpack的配置文件探究
  • 百度贴吧爬虫node+vue baidu_tieba_crawler
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 每个JavaScript开发人员应阅读的书【1】 - JavaScript: The Good Parts
  • 如何选择开源的机器学习框架?
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 正则表达式小结
  • ​2021半年盘点,不想你错过的重磅新书
  • ​Spring Boot 分片上传文件
  • #QT 笔记一
  • #QT项目实战(天气预报)
  • $.ajax,axios,fetch三种ajax请求的区别
  • $refs 、$nextTic、动态组件、name的使用
  • (02)Hive SQL编译成MapReduce任务的过程
  • (14)Hive调优——合并小文件
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (附源码)springboot高校宿舍交电费系统 毕业设计031552
  • (剑指Offer)面试题34:丑数
  • (三)终结任务
  • (三十)Flask之wtforms库【剖析源码上篇】
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • (转)Linux整合apache和tomcat构建Web服务器
  • (自用)gtest单元测试
  • .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .NET 读取 JSON格式的数据
  • .NET 分布式技术比较
  • .NET牛人应该知道些什么(2):中级.NET开发人员