0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

堆内存和栈内存的区别是什么

汽车电子技术 来源:程序喵大人 作者:程序喵大人 2023-02-21 13:54 次阅读

大家好,我是程序喵。

这篇文章分享一个面试中经常被问到的知识点:堆内存和栈内存有什么区别?平时开发应该使用堆内存还是栈内存?

要回答这个问题,我们首先需要知道什么是堆内存,什么是栈内存,它们的分配和回收有什么特点?


先介绍下栈内存:

栈内存是为线程留出的临时空间,每个线程都有一个固定大小的栈空间,而且栈空间存储的数据只能由当前线程访问,所以它是线程安全的。

栈空间的分配和回收是由系统来做的,我们不需要手动控制。

当一个函数调用时,系统就会为该函数的调用分配栈空间,当函数返回后,系统就会自动回收这块空间,同理,下次其它函数调用和返回,系统还是会自动分配和回收空间。

那它是怎么分配和回收的呢?

可以看这两个动画

图片

栈空间的大小是固定的,它有一个水位线,标识栈空间的分配状态,水位线里面的表示已经分配,然后这个水位线会根据函数调用和返回的情况自动调整。

这里可以看到,栈空间的分配和回收非常简单,只需要调整水位线位置就可以了,没有任何多余操作。


那堆内存呢?

我们平时在C语言C++中使用malloc和new分配的内存就是堆内存,堆内存的一大特点就是大小不固定,可以动态扩容,空间由程序员动态分配,更加灵活。

然而,既然有优点也必然伴随着缺点。

第一个缺点就是它容易产生内存泄露,malloc出来的没有free,new出来的如果没有delete,都会产生内存泄露,真正项目内存泄露产生的情况肯定比这个复杂的多。

第二个缺点,容易产生内存碎片,在分配和回收时需要对很多内存碎片进行整理,效率较低,具体可以看这个动画。

微信截图_20230105161930.png

所以才会有很多自定义的内存分配器,但它肯定还是没有栈空间分配回收速度快。

第三个缺点,线程不安全,它不像栈内存是线程独立的,堆内存可以被一个进程内所有的线程访问,多线程操作就容易产生问题,很多奇奇怪怪的操作就是这么引起的。


那什么变量存储在栈上,什么存储在堆上呢?普通的A a,这种就是都存储在栈上,当使用new和malloc分配的空间会存储在堆上,看这个图:

图片

new出来的实际空间是在堆上分配,然后在栈上开辟一个指针大小的空间,这个空间有一个指针,指向堆上的那块内存,这样给变量和堆内存之间就关联起来了。


那什么情况下使用栈内存,什么情况下使用堆内存呢?

我整理出来了一个表,贴在这里:

速度
空间管理 高效,不会产生碎片 会产生内存碎片
访问权限 只能局部变量 可以访问全局变量
空间大小限制 操作系统限制 没有特定的限制
内存分配 连续 随机分配
分配和释放 编译器指令自动管理 程序员手动管理
开销
主要问题 空间小 内存碎片
灵活性 固定大小 可以resize

这里可以根据实际需求来决定使用哪类内存。

当然,其实也不用关注那么多,我一般就是大内存使用堆,局部变量小内存使用栈。

这里还涉及到很多其它知识点,比如进程的内存空间布局是怎么样的,栈空间会不会污染、堆内存具体是怎么分配和回收的。

具体在我的公众号里搜索吧,里面有很多相关文章。

最后是 提问环节 ,大家可以在评论区讨论一下哈。

  • 当定义一个vector a(100); a在哪块内存?那100a的空间又在哪里?
  • 当定义一个array a; a在哪块内存,那100个a的空间又在哪里?

参考链接

https://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap

https://www.guru99.com/stack-vs-heap.html

https://www.geeksforgeeks.org/stack-vs-heap-memory-allocation/

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 存储
    +关注

    关注

    12

    文章

    3856

    浏览量

    84660
  • 线程
    +关注

    关注

    0

    文章

    489

    浏览量

    19495
  • 栈空间
    +关注

    关注

    0

    文章

    5

    浏览量

    5410
收藏 人收藏

    评论

    相关推荐

    内存管理(中)

    内存管理(中) 欢迎研究ZigBee的朋友和我交流。。。
    发表于 08-11 19:16

    浅谈程序的内存布局

    前言1、什么是 User space 与 Kernel space?2、Linux 下一个进程里典型的内存布局是怎样的?3、什么是区?4、什么是区?5、malloc 算法是如何实现的?6
    发表于 12-26 01:39

    【原创】C语言中的动态内存-----内存

    作者:蔡琰老师(张飞实战电子高级工程师)C语言程序的动态内存分为内存区域和内存区域两种。
    发表于 07-07 14:18

    【原创】内存的那些事

    地址向高地址分配。在C语言中,内存在分配和释放的时候,是程序通过调用C语言的库函数完成的。这和内存的分配有区别
    发表于 07-12 09:48

    内存主要分为哪几个区

    一、五大内存分区:内存分成5个区,它们分别是、自由存储区、全局/静态存储区和常量存储区。1、
    发表于 07-15 07:33

    区别在哪

    以下引用网上资料 理解区别(1)区(stack):由编译器自动分配和释放,存放函数的参数值、局部变量的值等,其操作方式类似于数据结构中的
    发表于 08-11 09:18

    C语言单片机、堆栈的区别是什么?

    C语言单片机、堆栈的区别是什么?
    发表于 10-13 08:09

    单片机堆栈的区别内存分配的方式

    目录一、区(HEAP)二、区(STACK)三、堆栈的区别四、内存分配的方式五、堆栈溢出六、总结一、区(HEAP)
    发表于 11-24 06:29

    STM32中的区别是什么

    区别是什么?的空间是如何进行分配的?
    发表于 11-29 07:05

    内存管理程序结构

    内存管理程序结构内存分配方式内存管理函数mallocrealloccallocmemsetfree
    发表于 12-17 07:15

    区别是什么

    在回答完进程的虚拟地址空间布局之后(上一篇),面试官可能抓住深入展开。区别①管理方式:
    发表于 12-22 07:26

    什么是?什么是

    ,程序执行过程中溢出,极大可能的影响程序、系统的稳定,严重时会造成程序、系统的崩溃,所以堆栈溢出检测十分重要且必要。什么是,什么是
    发表于 12-22 06:09

    单片机区别在哪

    文末有图和程序帮助理解!!!区别可以用如下的比喻来看出:使用就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走不必理会切菜、洗菜等准备工作和洗碗、刷锅
    发表于 01-20 08:31

    电脑中硬盘和内存区别是什么

    很多购买电脑的同学仍然还不清楚内存和硬盘到底有什么区别,在电脑里面有什么作用,容易把内存当硬盘或把硬盘当内存,下面小编通俗易懂的来给大家讲讲硬盘跟
    发表于 12-22 11:13 9841次阅读

    内存套条和单条的区别

    同型号的内存条,套装往往要比单条还要贵一些。讲道理来说,同型号同容量同频率的内存条价格应该一样,但是实际上他们的价格是有区别的,为什么会有这样的差别呢?内存套条和单条有什么
    发表于 05-25 10:11 4320次阅读