C语言存储结构总结
在C语言中,数据根据其类型和声明方式被存储在不同的内存区域。以下是各类数据存储位置的详细总结:
内存五大分区
存储区 | 存储内容 | 生命周期 | 特点 |
---|---|---|---|
代码区(.text) | 程序代码(机器指令) | 整个程序运行期 | 只读 |
常量区(.rodata) | 字符串常量、const全局变量 | 整个程序运行期 | 只读 |
全局/静态区(.data/.bss) | 全局变量、静态变量 | 整个程序运行期 | 初始化的在.data,未初始化的在.bss |
堆区(heap) | 动态分配的内存(malloc等) | 直到free释放 | 手动管理,空间大 |
栈区(stack) | 局部变量、函数参数 | 函数执行期间 | 自动管理,空间有限 |
各类型数据存储位置
基本数据类型
int global_var; // .bss段(未初始化)
const int c_global = 10; // .rodata段
static int static_var; // .bss段(未初始化)void func() {int local_var; // 栈区
}
指针类型
int *p; // 全局指针在全局区void func() {char *str; // 指针变量在栈区char *s1 = "abc"; // "abc"在常量区char s2[] = "abc"; // 数组内容在栈区int *p = malloc(100); // 指向堆区内存
}
数组类型
int global_arr[10]; // .bss段(未初始化)void func() {char local_arr[20]; // 栈区
}
结构体/联合体
struct Point {int x, y;
};struct Point p1; // 全局结构体在全局区void func() {struct Point p2; // 局部结构体在栈区
}
动态分配内存
int *arr = malloc(10*sizeof(int)); // 堆区
字符串常量
char *str = "Hello"; // "Hello"在.rodata段
特殊说明
-
register变量:请求编译器将变量存储在CPU寄存器中(不保证成功)
register int i; // 可能存储在寄存器
-
volatile变量:告诉编译器不要优化,每次从内存读取
volatile int counter; // 存储位置不变,但访问方式特殊
-
const变量:
- 全局const:常量区(.rodata)
- 局部const:栈区(但内容不可修改)
-
static局部变量:虽然作用域是局部的,但生命周期和存储位置与全局变量相同(全局/静态区)
内存布局示意图
高地址
┌─────────────┐
│ 栈区 │ ← 向下增长
├─────────────┤
│ ↓ │
│ (空闲) │
│ ↑ │
├─────────────┤
│ 堆区 │ ← 向上增长
├─────────────┤
│ .bss段 │ (未初始化的全局/静态变量)
├─────────────┤
│ .data段 │ (已初始化的全局/静态变量)
├─────────────┤
│ .rodata段 │ (常量、字符串字面量)
├─────────────┤
│ .text段 │ (程序代码)
└─────────────┘
低地址
验证示例
#include <stdio.h>
#include <stdlib.h>int global_init = 10; // .data段
int global_uninit; // .bss段
const int global_const = 5;// .rodata段int main() {static int static_var; // .bss段int local_var; // 栈区char *str_literal = "Hello"; // "Hello"在.rodata段char str_array[] = "World"; // 栈区(数组)int *heap_ptr = malloc(100); // 堆区printf("全局初始化变量: %p\n", &global_init);printf("全局未初始化变量: %p\n", &global_uninit);printf("全局常量: %p\n", &global_const);printf("静态变量: %p\n", &static_var);printf("局部变量: %p\n", &local_var);printf("字符串字面量: %p\n", str_literal);printf("字符数组: %p\n", str_array);printf("堆内存: %p\n", heap_ptr);free(heap_ptr);return 0;
}