一、栈的堆的本质区别

堆和栈都是程序运行时数据在内存中存储的不同区域。

他们的本质区别在于管理权限权归属: 栈由编译器自动管理,堆由程序员手动管理,或由智能指针托管

二、栈与堆的六个比对

1、生命周期不同

栈:绑定作用域

  • 变量在声明时创建,离开作用域{}时,立刻析构销毁,确定性强

堆:绑定手动操作

  • new、malloc操作后一直存在,直到delete,free被调用或进程结束,不确定强。

2、分配方式不同

栈由编译器隐式分配:

  • 直接修改栈顶指针来划分空间

堆由程序员显示申请:

  • 需要调用操作系统提供的接口brk或mmap,在空闲链表中查找内存块

3、速度

栈>堆

  • 栈分配仅需一条cpu指令,堆分配涉及操作系统调用,和空闲链表遍历

  • 建议频繁小对象的创建操作,使用栈而不是使用new

4、大小

栈极小:默认只有1-8MB

  • 栈溢出会报错 stack overflow

堆很大:

  • 受系统虚拟内存限制,可达GB级别

5、碎片问题

栈无碎片:

  • 严格的LIFO

堆有碎片:

  • 在申请与销毁内存时造成内存缝隙

6、线程安全

栈天然线程安全:

  • 每个线程拥有独立的栈空间,局部变量是线程私有的

堆默认线程不安全:

  • 堆内存是所有线程共享的。

三、其他内存区域

  • 除了栈和堆外,内存区域还有 静态存储区 与 常量区

  • 字符串string存储位置,如果是端字符串会进行优化存储在栈上,长字符串使用堆保存

四、栈与堆在工程中的使用

使用原则:能用栈则栈,必须用堆则使用智能指针托管

  • 小数据,确定的生命周期使用栈

  • 大数据,多态对象,容器内部用堆

  • 现代C++建议尽量不用new/delete,改为使用智能指针unique_ptr 与 make_unique来申请内存。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐