一句话:"全局住酒店(静态区),局部住民宿(栈),malloc 自己买房(堆)——前两个店家收房,最后一个自己管。"
C 内存分三区——静态区(程序期)、栈(函数调用期)、堆(malloc 到 free)。每个变量必答三连问:住哪?活多久?谁收?
int g; / static int s; → 程序启动分配、结束回收,自动清零,活整个程序期void f(){ int x = 5; } → 调用时分配、返回自动销毁,快但量小(KB 级)int *p = malloc(100); → malloc 分配、free 手动释放,不 free 就泄漏| 静态区 | 栈 | 堆 | |
|---|---|---|---|
| 谁分配 | 程序启动 | 函数调用时 | malloc |
| 生命周期 | 整个程序期 | 函数调用期间 | malloc → free |
| 谁管释放 | 系统自动 | 系统自动 | 程序员 |
| 大小/速度 | 固定,快 | 小(KB 级),很快 | 大,慢(要查找空闲块) |
| 自动初始化 | ✅ 清零 | ❌ 垃圾值 | ❌ 垃圾值 |
陷阱:函数内 static int x; 住静态区不是栈(static 改的是存储期)。
const char *s = "hello"; → 字符串字面量在只读数据区(静态区一族),不能修改int g[10]; 元素默认全是 0;函数内 int l[10]; 是垃圾值(静态区自动清零 vs 栈不初始化)void f(){ int *p = malloc(100); } 函数返回后 → 指针没了,堆内存还占着没人能 free → 内存泄漏| 相邻概念 | 和本主题的关系 | 孤立理解会犯的错 |
|---|---|---|
| 程序分段 | 三区放一起讲:代码段/数据段/BSS/堆/栈——本题是三区的微观版 | 以为堆栈是"段"(实际是动态区) |
| 堆 vs 栈 | 谁分配、谁回收、速度、碎片——三区里最常单独拷的对比 | 以为栈也像堆一样会碎片化 |
| static | static 局部 = 静态区,不是栈 | 以为函数内声明就住栈 |
| 内存碎片 | malloc/free 反复 → 堆碎片化 | 以为碎片只有大小问题,不关心分配失败 |
2026-08-03
每主题一页,复习时只翻本目录。