C语言堆和栈的区别是什么?

一、问题

栈是存放函数的所有动态局部变量及函数调⽤和返回有关信息的⼀块内存。它为调试程序提供了⼀种功能,能够显示⼀个已被调⽤的函数的列表,这是调试程序时⼀种很有⽤的⼿段。

堆提供 malloc( ) , calloc( ) 和 realloc( ) 等函数获取内存空间的⼀块内存。下⾯采⽤对⽐的形式分别介绍堆和栈的作⽤,以及它们的区别。

二、解答

1. 堆和栈的作⽤

(1)栈的内存管理严格遵循先进后出的顺序,即释放栈中对象所占内存时的顺序刚好与为这些对象分配栈中内存时的顺序相反,这⼀点正是实现函数调⽤所需要的。从栈中分配内存效率特别⾼,C语⾔编译程序能产⽣如此好的代码的原因之⼀就是充分利⽤了栈。

(2)从堆中获取内存⽐从栈中获取内存要慢得多,但是堆的内存管理却⽐栈灵活得多。任何时候都可以从堆中获取内存,⽽且在释放堆中对象所占内存时,可以按任意顺序进⾏。数据对象使⽤栈中内存⽐使⽤堆中内存程序运⾏更快。但是,有时候使⽤堆中内存可以改善⼀种算法,从⽽使它更快,或者更灵活,因此使⽤堆或栈要折中考虑。

2. 堆和栈的区别

在了解了堆和栈各⾃的⽤途后,从两者的申请⽅式、申请后系统的响应、申请⼤⼩的限制、申请效率的⽐较和存储内容各⽅⾯了解它们的实质区别。

(1)申请⽅式

栈是由系统⾃动分配。如声明在函数中的⼀个局部变量 "int i;",系统会⾃动在栈中为 i 开辟内存空间。⽽堆是程序员⾃⼰申请,同时指明⼤⼩。在C语⾔中,堆提供 malloc( ) ,calloc( ) 和 realloc( ) 等函数获取内存空间的⼀块内存,如 " buffer=(int*)malloc(256) "是为 buffer 分配了⼀个256 字节⼤⼩的 int 型内存空间。

(2)申请后系统的响应

只要栈的剩余空间⼤于所申请空间,系统将为程序提供内存,否则将报异常,提示栈溢出。⽽堆则是⾸先确定操作系统有⼀个记录空闲内存地址的链表。当系统收到程序的申请时,会遍历此链表,寻找第⼀个⼤于所申请空间的堆结点, 然后将该结点从空闲结点链表中删除,并将该结点的控件分配给程序。

(3)申请⼤⼩的限制

在 windows 下,栈是向低地址扩展的数据结构,是⼀块连续的内存区域。它的最⼤容量是预先规定好的,如果申请的空间超过栈剩余的空间,将会提示溢出,能从栈获得的空间较⼩。⽽堆是向⾼地址扩展的数据结构,是不连续的内存区域。

这是因为系统是⽤链表来存储空闲内存地址的,⽽链表的遍历⽅向是由低地址向⾼地址, 堆的⼤⼩受限于计算机系统中有效的虚拟内存。因此,堆获得的空间⽐较灵活,也⽐较⼤。

(4)申请效率

在申请⽅式中,已经得知栈是由系统⾃动分配的,速度⽐较快,不容易控制。⽽堆是由 new 分配的内存,速度⽐较慢,⽤起来较⽅便。

(5)存储内容

在函数调⽤时,第⼀个进栈的是主函数中的下⼀条指令(函数调⽤语句的下⼀条可执⾏语句)的地址,然后是函数的各个参数。在⼤多数 C 编译器中,参数是由右往左⼊栈的,然后是函数中的局部变量。

注意,静态变量是不⼊栈的。当本次函数调⽤结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是 主函数中的下⼀条指令,程序由该点继续运⾏。⽽堆⼀般是在堆的头部⽤⼀个字节存放堆的⼤⼩,堆中的具体内容由程序员安排。

三、总结

通过对栈和堆的⽐较,⼤致了解了堆和栈的区别,以及⽤途。其实,栈和堆的关系可以理解为机洗⾐服和⼿洗⾐服。全⾃动洗⾐机洗⾐服,将所有的脏⾐服放进去,倒上⽔, 放上洗⾐液就可以了。这样很便捷,但是灵活度和⾃由度较⼩。⼿洗⾐服虽然很累,但是可以将⾃⼰认为⽐较脏的局部地⽅多洗洗或分类洗,灵活度较⼤。

相关推荐
Never_Satisfied12 分钟前
在JavaScript / HTML中,div容器在内容过多时不显示超出的部分
开发语言·javascript·html
艾莉丝努力练剑42 分钟前
【C++STL :stack && queue (一) 】STL:stack与queue全解析|深入使用(附高频算法题详解)
linux·开发语言·数据结构·c++·算法
胡萝卜3.01 小时前
深入理解string底层:手写高效字符串类
开发语言·c++·学习·学习笔记·string类·string模拟实现
kyle~1 小时前
计算机系统---CPU的进程与线程处理
linux·服务器·c语言·c++·操作系统·计算机系统
西柚小萌新1 小时前
【Python从入门到精通】--Pycharm增加内存
开发语言·python·pycharm
不爱编程的小九九1 小时前
小九源码-springboot082-java旅游攻略平台
java·开发语言·旅游
只是懒得想了1 小时前
用C++实现一个高效可扩展的行为树(Behavior Tree)框架
java·开发语言·c++·design-patterns
yan8626592461 小时前
于 C++ 的虚函数多态 和 模板方法模式 的结合
java·开发语言·算法
小此方2 小时前
C语言自定义变量类型结构体理论:从初见到精通(下)
c语言·数据结构·算法
Small___ming2 小时前
【Python基础】Python路径操作全解析:os.path、glob与pathlib从入门到精通
开发语言·python