鱼C论坛

 找回密码
 立即注册
查看: 2094|回复: 0

32.堆与栈的区别

[复制链接]
发表于 2013-3-12 18:19:45 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 (@_@) 于 2013-3-12 18:20 编辑
$ R! V7 {+ H' e( k1 C4 v: X! H
. [1 f% J6 I" O首先要明确一个概念:堆栈不是一个概念,堆是堆,栈是栈,堆栈不能合起来+ f% P: E4 ^8 h  X4 i+ [
1.内存申请方式不同
+ b5 J; W9 o7 s9 ?! J; y栈:由系统自动分配,例如我们在函数中声明一个局部变量int i;那么系统就会自动在栈中为变量i开辟空间。. S  `. X7 j9 U; }$ ?& ]
堆:需要程序员自己申请,因此也需要指明变量的大小。' y6 [. T, M3 o9 g3 ~" G! c- u) w
2.系统响应不同! [  X' m4 z$ {' n2 V6 E, s
栈:只要栈的剩余空间大于所申请的空间,系统将为程序提供内存,否则将提示overflow,也就是栈溢出。7 Z1 |$ O4 y, m& C: C) X
堆:系统收到程序申请空间的要求后,会遍历一个操作系统用于记录内存空闲地址的链表,当找到一个空间大于所申请空间的堆结点后,就会将该结点从记录内存空闲地址的链表中删除。并将该结点的内存分配给程序,然后在这块内存区域的首地址处记录分配的大小,这样我们在使用delete来释放内存的时候,delete才能正确的识别并删除该区域的所有变量。另外,我们申请的内存空间与堆结点的内存空间不一定相等,这时系统就会自动将堆结点上多出来的那一部分内存空间回收到空闲链表中。
5 T5 J5 [" U2 F. d3.空间大小的不同" [7 j/ Z2 P  Q5 m! s$ _9 y/ b
栈:在windows下,栈是一块连续的内存区域,它的大小是2M,也有的说是1M,总之该数值是一个编译时就确定的常数。是由系统预先根据栈顶的地址和栈的最大容量定义好的。假如你的数据申请的内存空间超过栈的空间,那么就会提示overflow。因此,别指望栈能存储比较大的数据。( I3 t- C; E% C. ^5 \: R* Y
堆:堆是不连续的存储区域,各块区域由链表将它们串联起来,链表将各个不连续的内存区域连接起来,这些串联起来的内存空间叫做堆,它的上限是由系统中有效的虚拟内存来定的。因此获得的空间比较大,而且获得空间的方式也比较灵活。( I4 L( i3 d3 O" Q! ^
4.执行效率不同
  V# W! I, T6 C6 f# n3 B& U4 J栈:栈由系统自动分配,因此速度较快。但是程序员不能对其进行操作。9 x& O8 D, ?8 ^& G
堆:堆是由程序员分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来很放便。
* ?' e* l2 ?: D5.执行函数不同" r$ H* F5 v" T8 K! t! T$ J
栈:在函数调用时,第一个进栈的是被调用函数下一行的内存地址。其次是函数的传参,假如参数多于一个,那么次序是从右往左。最后才是函数的局部变量。' a* d' e% t9 I4 h! R$ j' _" H
  由于栈的先进后出原则,函数结束时正好相反,首先是局部变量先出栈,然后是参数,次序是从左到右,这时所有的变量都已出栈,指针自然地指到第一个进栈的那行内存地址,也就是被调用函数的下一行内存地址。程序根据该地址跳转到被调用函数的下一行自动执行。
- O0 k) s( `) [5 W! N$ Z; z堆:堆是一大堆不连续的内存区域,在系统中由链表将它们串联起来,因此在使用的时候必须由程序员来安排。它的机制是很复杂的,有时候为了分配一块合适的内存,程序员需要按照一定的算法在堆内存中搜索可用的足够大小的空间,如果没有满足条件的空间,那么就要向系统发出增加一部分内存空间,这样才有机会分到足够大小的内存,然后将计算后的数值返回。显然,堆的运行效率要比栈低得多,而且容易产生碎片。但是好处是可以存储相当大的数据,并且一些细节也可以由程序员来安排。
" a! `/ t: q) B9 k) i4 _' N/ M
小甲鱼最新课程 -> https://ilovefishc.com

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-3-17 00:47

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表