跳转至

内存空间分布

内存分布模型

(高地址)

  • 动态区
  • 静态区
  • 全局未初始化区(.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 中