The Stack
什么是堆栈?它是计算机内存中的一个特殊区域,存储着被函数(包括main()函数)创建的临时变量。它由CPU非常紧密的管理和优化,是一种LIFO
(后进先出)的数据结构。函数每一次定义一个新的变量,它都会被放进堆栈中。当函数执行完成退出时,被这个函数放到堆栈里的变量都会被释放,也就是从堆栈中被删除。一旦堆栈变量被释放,对于其他的堆栈变量而言,这个特殊的内存区域就变的可用。
使用堆栈来存储变量的好处是内存是由系统来管理,你不必手动的分配和释放内存。更重要的是,CPU管理堆栈内存非常的高效,从里面读写变量都是非常快速的。
对于堆栈还有一个要注意的地方,堆栈是有小大限制的,并且随着底层操作系统的不同,这个大小也是不同的。
总结一下:
- 堆栈占用的大小会随着函数push和pop局部变量而增加和减小
- 堆栈内存不需要自己手动管理,它的分配和释放都是自动
- 堆栈有大小限制
- 堆栈变量仅在创建它们的函数运行时存在
The Heap
堆是计算机内存中不会自动为您管理的区域,并且不受CPU严格管理。它是内存中更自由浮动的区域(并且更大)。要在堆上分配内存,必须使用内置的C函数malloc()
或calloc()
。在堆上分配内存后,一旦不再需要,要使用free()
释放该内存。如果不这样做,程序将发生所谓的内存泄漏,也就是说,堆上的内存仍将被保留(并且其他进程将无法使用)。
与堆栈不同,堆对变量大小没有限制(除了计算机物理内存限制以外)。相比于堆栈,堆内存的读写要稍慢一些,因为必须使用指针来访问堆上的内存数据。
还有一点和堆栈不同的是,在堆上创建的变量可以在程序中任何位置的任何函数访问。堆变量本质上是全局的。
利弊之分
Stack
- 非常快的访问速度
- 不必显示的取消分配的变量
- 内存空间由CPU高效的管理,因而不会变的碎片化
- 只能局部变量
- 变量不能调整大小
Heap
- 变量可以被全局访问
- 没有内存大小的限制
- 访问速度相对于堆栈要慢一些
- 无法保证有效利用空间,随着时间的推移,内存块可能会随着内存块的分配而碎片化,然后释放
- 必须手动的管理内存(分配和释放)
- 变量可以使用
realloc()
调整大小
如何使用?
什么时候应该使用堆,什么时候应该使用堆栈?
如果您需要分配一个大的内存块(例如,一个大array
或一个大的struct
),并且需要长时间保持该变量(例如全局变量),则应该在堆上分配它。如果您要处理的变量相对较小,并且只要使用它们的函数时使用,那么您应该使用堆栈,它更容易,更快捷。如果您需要像数组和结构这样的变量可以动态更改大小(例如,可以根据需要增加或缩小的数组),则可能需要在堆上分配它们,并使用动态内存分配函数,如malloc()
,calloc()
,realloc()
和free()
来“手动“管理该内存。