内存空间分布
内存分布模型¶
(高地址)
- 动态区
- 栈
- 堆
- 静态区
- 全局未初始化区(.bss)
- 全局初始化区(.data)
- 只读数据段
- 代码段
(低地址)
其中,动态区 = RAM,静态区 = ROM
栈区(stack)¶
- 临时创建的局部变量
- 调用函数的传参、返回值
- const 定义的局部变量
堆区(heap)¶
- 动态分配的内存
全局未初始化区(.bss)¶
- 未初始化全局变量
- 初始化为 0 的全局变量、静态变量
- .bss 不占用可执行文件空间,内容由操作系统初始化
全局初始化区(.data)¶
- 已初始化的全局变量
- 静态变量
- .data 占用可执行文件空间,内容由程序初始化
- const 定义的全局变量放在 .rodata 段
常量区(.rodata)¶
- const 定义的常量
- 字符串常量
代码段(.text)¶
- 程序代码
代码示例¶
#include <stdio.h>
int g_inited = 10; /*!< .data */
int g_uninit; /*!< .bss */
const int g_const = 20; /*!< .rodata */
int main(int argc, char *argv[])
{
int value = 20; /*!< 栈区 */
static int s_value = 30; /*!< 静态变量,.data */
const int value2 = 40; /*!< value2 存放在栈区 */
const char *str = "hello world"; /*!< str 放在栈区,"hello world" 放在常量区 */
int *buffer = (int *)malloc(sizeof(int) * 10); /*!< 动态分配的内存 */
printf("main: %p", main);
printf("str: %p\n", str);
printf("g_inited: %p\n", (void *)&g_inited);
printf("s_value: %p\n", (void *)&s_value);
printf("g_uninit: %p\n", (void *)&g_uninit);
printf("value: %p\n", (void *)&value);
printf("buffer: %p\n", buffer);
free(buffer);
return 0;
}
存储介质¶
RAM¶
随机存储器,分两种:
- 静态 RAM(SRAM)
- 动态 RAM(DRAM)
ROM¶
只读存储器,相比 RAM 读写速度慢,断电后数据不丢失,常用来存放一次性写入的程序和数据
Flash¶
闪存,断电后数据不丢失,可多次擦写
现在 Flash 已经取代了 ROM,成为嵌入式系统常用的存储介质
存放位置¶
FLASH = Code + RO + RW RAM = RW + ZI + 堆栈
| - | - | - |
|---|---|---|
| 栈区(Stack) | 包含在 RW-data(读写数据存储区) | 函数传参,局部变量等 |
| 堆区(Heap) | 包含在单片机的 sram 中的(读写数据存储区) | 自己申请释放 |
| 全局区(静态区)(static) | 全局变量、全局静态变量、局部静态变量(读写数据存储区) | SRAM |
| 一般未初始化的变量 | ZI-data(零初始化存储区) | SRAM |
| 文字常量(const) | RO-data(只读存储区) | FLASH 中 |
| 函数代码 | 存放函数体的二进制代码 Code(数据代码区) | 存储在 Flash 中 |