| 上一篇 | 下一篇 |
|---|---|
| C/C++ 中 sizeof 和 strlen 的区别 |
栈和堆的区别?
-
内存分配方式
-
栈:由系统自动分配和释放。函数调用时,局部变量、函数参数等会自动压入栈;函数返回时,这些数据自动弹出并释放。
-
堆 :由程序员手动申请和释放(如 C/C++ 中使用
malloc/free或new/delete)。若不手动释放,可能造成内存泄漏。
-
-
内存管理
-
栈:遵循"后进先出"(LIFO)原则,结构简单,管理高效。
-
堆:内存分配自由,可以动态申请任意大小的内存块,但管理复杂,容易产生碎片。
-
-
生命周期
-
栈:变量的生命周期与作用域绑定,离开作用域即被销毁。
-
堆:变量生命周期由程序员控制,直到显式释放或程序结束。
-
-
访问速度
-
栈:访问速度快,因为内存连续且由硬件支持(如寄存器指针直接操作)。
-
堆:访问速度相对较慢,涉及指针间接寻址,且可能触发操作系统内存管理机制。
-
-
空间大小
-
栈:通常较小(例如几 MB),受操作系统限制,容易发生栈溢出(如递归过深)。
-
堆:空间较大(受限于虚拟内存),适合存储大对象或长期存在的数据。
-
-
用途示例
-
栈:存储函数局部变量、返回地址、参数等。
-
堆:存储动态数据结构(如链表、树)、大数组、需要跨函数/模块共享的数据。
-
-
线程安全性
-
栈:每个线程有自己的栈,天然线程安全。
-
堆:多个线程共享堆,需加锁等同步机制避免竞争条件。
-
总结对比表:
| 特性 | 栈(Stack) | 堆(Heap) |
|---|---|---|
| 分配方式 | 自动(系统管理) | 手动(程序员管理) |
| 生命周期 | 作用域结束自动释放 | 手动释放或程序结束 |
| 访问速度 | 快 | 较慢 |
| 内存大小 | 小(有限) | 大(受限于虚拟内存) |
| 碎片问题 | 无 | 可能存在 |
| 典型用途 | 局部变量、函数调用 | 动态分配、大对象、共享数据 |
| 线程安全 | 是(每个线程独立栈) | 否(需同步机制) |