C++ 内存分区 堆区

一、堆区是什么?

堆区是 C++ 程序运行时,由程序员手动申请、手动释放的一块动态内存区域 。它不属于任何函数,不属于任何局部作用域,生命周期完全由程序员自己控制

  • 栈:系统自动管
  • 堆:程序员自己管
  • 全局区:程序启动就有,结束才没
  • 堆:想用就 new,不用就 delete

二、堆区的核心特点

1. 内存分配方式:动态分配

程序运行过程中随时可以申请、随时可以释放,大小可以任意指定。

2. 内存不连续

堆是链表结构 管理空闲块,多次申请的内存地址不连续

3. 空间巨大

栈只有几 MB,堆可以用到 几 GB(受操作系统限制)。

4. 分配速度比栈慢

因为需要遍历空闲链表、分配、标记、防止碎片。

5. 生命周期由程序员控制

  • new → 分配
  • delete → 释放
  • 不释放 → 内存泄漏
  • 释放后再用 → 野指针、崩溃

6. 多线程共享

同一个进程内的所有线程,共享同一个堆空间


三、堆区用来存什么?

  1. 动态大小的数组(运行时才知道大小)
  2. 大对象(太大栈放不下)
  3. 需要跨函数、跨作用域使用的对象
  4. 容器底层(vector、string、map 全在堆上)

四、堆区的使用方式(C++ 标准)

1. 申请单个变量

cpp

运行

复制代码
int* p = new int(100);  // 堆上分配 int,值=100

2. 申请数组

cpp

运行

复制代码
int* arr = new int[10]; // 堆上分配 10 个 int 的数组

3. 释放内存

cpp

运行

复制代码
delete p;       // 释放单个变量
delete[] arr;   // 释放数组 必须加[]

4. 最规范写法

cpp

运行

复制代码
int* p = new int(20);
delete p;
p = nullptr;  // 释放后置空,避免野指针

五、堆区底层原理(非常重要)

1. 堆内存如何分配?

操作系统维护一个 空闲内存链表

  • new → 遍历链表找一块足够大的内存
  • 标记为已使用
  • 返回地址给程序

2. 堆内存增长方向

从低地址 → 高地址(和栈相反)

3. 堆内存不会自动释放

只有两种情况会释放:

  1. 程序员 delete
  2. 程序结束,OS 回收

六、堆区常见错误(90% 的人都踩过)

1. 内存泄漏(最常见)

cpp

运行

复制代码
void func() {
    int* p = new int(10);
} // 函数结束,p 销毁,但堆内存还在!泄漏了

2. 重复释放

cpp

运行

复制代码
int* p = new int;
delete p;
delete p; // 崩溃!重复释放堆内存

3. 释放后继续使用(野指针)

cpp

运行

复制代码
int* p = new int(10);
delete p;
*p = 20; // 严重错误!访问已释放的堆内存

4. new /delete 不匹配

cpp

运行

复制代码
int* arr = new int[10];
delete arr; // 错误!应该用 delete[]

5. 不初始化就使用

cpp

运行

复制代码
int* p = new int; // 未初始化,值是随机垃圾数

七、堆 vs 栈(最清晰对比)

表格

特点 栈区(stack) 堆区(heap)
谁管理 系统自动分配、自动释放 程序员手动 new/delete
速度 极快 较慢
空间 小(MB 级别) 大(GB 级别)
连续性 连续内存 不连续
生命周期 函数结束即销毁 手动控制
碎片 无碎片 容易产生内存碎片
方向 高地址 → 低地址 低地址 → 高地址
报错 栈溢出 内存不足、野指针、重复释放

八、堆区使用规范(企业级标准)

  1. 谁申请,谁释放
  2. new 必须配对 deletenew[] 配对 delete[]
  3. 释放后指针立刻置空 nullptr
  4. 不要返回栈指针,但可以返回堆指针
  5. 能用栈就不用堆,堆更耗性能
  6. 现代 C++ 尽量用 智能指针(unique_ptr/shared_ptr) 自动管理堆内存,避免泄漏
相关推荐
折哥的程序人生 · 物流技术专研6 小时前
Java面试85题图解版 · 特别篇:2026后端高频面试题复盘(算法底层逻辑+高并发架构设计全解析,附Java实战代码)
java·网络·数据库·算法·面试
xxie1237946 小时前
return与print
开发语言·python
秋96 小时前
从 Python 后端工程师转型 AI Engineer(AI 工程化)的完整补课清单(2026实战版)
开发语言·人工智能·python
一条泥憨鱼6 小时前
【Redis】数据类型和常用命令
java·数据库·redis·后端·缓存
云烟成雨TD7 小时前
Spring AI Alibaba 1.x 系列【78】沙箱(Sandbox)
java·人工智能·spring
程序员二叉7 小时前
【Java】 异常高频面试题精讲 | 易错点+对比总结
java·开发语言·面试
玖玥拾7 小时前
C/C++ 基础笔记(十四)多态与模板编程
c语言·c++·多态·模板
周航宇JoeZhou7 小时前
JB3-9-SpringAI(二)
java·ai·agent·多智能体·调度·智能体·观察
好家伙VCC7 小时前
Web Components主题热切换方案揭秘
java·前端
慕木沐7 小时前
Google ADK Java 1.0版本 核心机制与实战 Demo
java·开发语言·python