C语言中各种变量的内存分布

我来帮你梳理一下C语言中各种变量的内存分布,用个形象的比喻和总结让你再也不混淆。

一、内存布局图(先看全貌)

内存地址(高地址) ──┐

栈 (Stack)

↓ 生长

├───

堆 (Heap)

↑ 生长

├───

BSS段 (未初始化)

Data段 (已初始化)

Text段 (代码)

内存地址(低地址) ──┘

二、分门别类说清楚

  1. 全局变量

int global_var; // 未初始化全局变量

int global_init = 10; // 已初始化全局变量

未初始化全局变量 → BSS段

程序启动时自动清零

不占可执行文件空间

已初始化全局变量 → Data段

初始值保存在可执行文件中

程序加载时读入内存

  1. static全局变量

static int static_global; // 在BSS段

static int static_global2 = 20; // 在Data段

内存位置同普通全局变量

区别:作用域限于当前文件

记忆:static只改作用域,不改存储位置

  1. static局部变量

void func() {

static int static_local; // 在BSS段

static int static_local2 = 30; // 在Data段

}

同样在Data/BSS段

区别:只在第一次执行时初始化

作用域是函数内,但生命周期是全局

  1. 局部变量(非static)

void func() {

int local_var; // 在栈上

int local2 = 40; // 在栈上

}

都在栈(Stack)上

函数返回时自动释放

生存期 = 函数执行期间

  1. 动态分配内存

int *p = malloc(100); // 在堆(Heap)上

由程序员手动管理

malloc/new在堆上分配

需要free/delete释放

三、快速记忆口诀

口诀1:看三要素

  1. 作用域(哪里能用)

  2. 生存期(活多久)

  3. 存储位置(住哪里)

口诀2:位置判断

  • 有static → Data/BSS(看是否初始化)

  • 无static且在函数内 → 栈

  • 无static且在函数外 → Data/BSS

  • malloc/free → 堆

口诀3:初始值

  • 已初始化 → Data段

  • 未初始化 → BSS段(自动清零)

  • 局部变量(栈上)初始值随机!

四、实战代码示例

#include <stdio.h>

#include <stdlib.h>

// 全局变量

int g_uninit; // BSS段

int g_init = 100; // Data段

// static全局变量

static int sg_uninit; // BSS段

static int sg_init = 200; // Data段

void test() {

// 局部变量

int local = 10; // 栈

int local_uninit; // 栈(值随机!)

// static局部变量

static int sl_uninit; // BSS段

static int sl_init = 300; // Data段(只初始化一次!)

// 动态分配

int *heap_var = malloc(sizeof(int)); // 堆

*heap_var = 400;

printf("栈变量: %d\n", local);

printf("堆变量: %d\n", *heap_var);

printf("static局部: %d (下次调用会累加)\n", ++sl_init);

free(heap_var);

}

int main() {

printf("全局未初始化: %d (自动为0)\n", g_uninit);

printf("全局已初始化: %d\n", g_init);

test();

test(); // 第二次调用,static局部变量会保持值

return 0;

}

五、常犯错误提醒

⚠️ 注意这些坑:

栈变量不能返回地址

int* bad_func() {

int local = 10;

return &local; // 错误!函数结束栈就释放了

}

static局部变量只初始化一次

void counter() {

static int count = 0; // 这行只执行一次!

count++;

}

未初始化的栈变量值是随机的

void danger() {

int x; // 值不确定!

printf("%d", x); // 可能崩溃

}

六、一张表总结

|---|---|---|---|---|
| 变量类型 |||||
| 存储位置作用域生命周期初始值全局已初始化 |||||
| Data段整个程序程序运行期指定值全局未初始化 |||||
| BSS段整个程序程序运行期自动清零static全局 |||||
| Data/BSS当前文件程序运行期同上static局部 |||||
| Data/BSS函数内程序运行期同上普通局部 |||||
| 栈(Stack)函数内函数执行期随机值动态分配 |||||

堆(Heap)由指针决定直到free程序员控制终极记忆法:

有static或不在函数里 → Data/BSS(全局区域)

在函数里且没static → 栈

自己malloc的 → 堆

这样记是不是清楚多了?多用几次就形成肌肉记忆了!

相关推荐
叫我辉哥e11 天前
### 技术文章大纲:C语言造轮子大赛
c语言·开发语言
进击的小头1 天前
行为型模式:策略模式的C语言实战指南
c语言·开发语言·策略模式
爱编码的小八嘎1 天前
C语言对话-5.通过任何其他名字
c语言
定偶1 天前
C语言入门指南
c语言·开发语言
的卢马飞快1 天前
【C语言进阶】给数据一个“家”:从零开始掌握文件操作
c语言·网络·数据库
我能坚持多久1 天前
D17—C语言结构体详解:从声明、对齐到位段应用
c语言·开发语言
willingli1 天前
c语言经典题目 91-100
c语言
傻乐u兔1 天前
C语音进阶————数据在内存中的存储2
c语言·开发语言·算法
二年级程序员1 天前
自定义类型:联合体与枚举
c语言
麒qiqi1 天前
ADC 的原理与实战
c语言·开发语言·单片机·嵌入式硬件