
by Amanda Jones on Unsplash
堆 (stack) 和 栈 (heap) 都是内存中的一块存储区,区别在于,堆 被设计用于 快速频繁 地分配、释放空间与读写数据,栈 被设计用于读写更 持久、更 巨量 的数据。
堆区 采用后进先出的 堆栈 (stack) 数据结构,整个区域是连续的;栈区 一般采用 链表 实现,区域内会产生碎片,具体取决于所处的系统平台如何实现了。
设计目的和实现结构也就决定了 堆区 速度更快,栈区 相对较慢。
堆区 可能会面临的一个问题是 空间不足,便 stack overflow 了。堆区的大小是固定的,在程序开始运行之前就已经决定了。
堆区的大小通常是由编译器或操作系统决定的,通常已足够大,永远不应被用尽,除非你无限循环了。
栈区 可能会面临的一个问题是 碎片太多。对其分配和释放得越频繁,则碎片越多,速度越慢。
C 语言中,局部变量默认都存在 堆区,由系统自动分配空间,并在函数返回后自动释放空间。而 栈区 的空间需要手工分配 (malloc()
) 和手工释放 (free()
),完全由程序员自己管理。
C++ 中,也可以用
new
和delete
来分配和释放空间。
除了 堆区 和 栈区 外,已初始化的 全局变量 和由 static
关键字限定的 静态变量 都存在 数据区 (data segment);未初始化的全局变量和静态变量则存在 BSS 区 (block started by symbol);还有源代码本身存储在 文本区 (text segment)。
数据区 (data segment) 也称 Initialized Data Segment,其内部又进一步分为 只读区 和 读写区,全局变量和静态变量中被
const
限定的就进入只读区。
BSS 区 又称 Uninitialized Data Segment,包含 未初始化的 和 初始化为 0 的 全局变量和静态变量,它们会在程序运行前被统一初始化为 0 或 null pointer。
文本区 也称 代码区 (code segment),某些由
const
限定的常量也仅在此区中存储一份拷贝。
最后,五区加总,便是一个 C/C++ 程序所占用的内存。




