单片机内存区域划分


一、C 语言内存分区

C 语言在内存中一共分为如下几个区域,分别是:

下面分别介绍各个区域。

1、栈区

栈区介绍:

  • 栈区由编译器自动分配释放,由操作系统自动管理,无须手动管理。
  • 栈区由编译器自动分配释放,由操作系统自动管理,无须手动管理。
  • 栈区上的内容只在函数范围内存在,当函数运行结束,这些内容也会自动被销毁。
  • 栈区按内存地址由高到低方向生长,其最大大小由编译时确定,速度快,但自由性差,最大空间不大。
  • 栈区是先进后出原则(LIFO),其操作方式数据结构中的栈是一样的。

存放内容:

  • 临时创建的局部变量存放在栈区。
  • 函数调用时,其入口参数存放在栈区。
  • 函数返回时,其返回值存放在栈区。
  • const 定义的局部变量存放在栈区。

栈的大小是有限的,通常 Visual C++ 编译器的默认栈的大小为 1MB,所以不要定义 int a[1000000] 这样的超大数组。

2、堆区

  • 堆区按内存地址由低到高方向生长,其大小由系统内存/虚拟内存上限决定,速度较慢,但自由性大,可用空间大。
  • 堆区用于存放程序运行中被动态分布的内存段,可增可减。
  • 可以有 malloc 等函数实现动态分布内存,不过它的存储空间一般是不连续的,所以会产生内存碎片。
  • 有 malloc 函数分布的内存,必须用 free 进行内存释放,否则会造成内存泄漏。
  • 注意它与数据结构中的堆是两回事,不过分配方式类似于链表。
char* p = new char[20];
// 这行代码在Heap中开辟了20个char长度的空间,同时在Stack上压入了p,
// 指针变量p存在于栈上,其值为刚刚在堆上开辟的空间的首地址。

3、全局区(静态区)

全局区由 .bss 段和 .data 段组成,可读可写。

通常是用于那些在编译期间就能确定存储大小的变量的存储区,但它用于的是在整个程序运行期间都可见的全局变量和静态变量。

  • .bss 段 ——未初始化
    • 未初始化的全局变量和未初始化的静态变量存放在 .bss段
    • 初始化为 0 的全局变量和初始化为0的静态变量存放在 .bss段
    • .bss段 不占用可执行文件空间,其内容由操作系统初始化。
  • .data段 ——已初始化
    • 已初始化的全局变量存放在 .data段
    • 已初始化的静态变量存放在 .data段
    • .data段 占用可执行文件空间,其内容由程序初始化。

注意,.bss段 只占运行时的内存空间而不占文件空间。在程序运行的整个周期内,.bss段 的数据一直存在

4、常量区

同样,常量区也是用于那些在编译期间就能确定存储大小的常量的存储区,并且在程序运行期间,存储区内的常量是全局可见的。这是一块比较特殊的存储去,他们里面存放的是常量,不允许被修改。

  • 字符串数字等常量存放在常量区。
  • const 修饰的全局变量存放在常量区。
  • 程序运行期间,常量区的内容不可以被修改。

常量数据段叫做 .rodata,即 read only,表示常量数据是不可修改的。一旦程序中对其修改将会出现段错误:

  • 程序中的常量不一定就放在 .rodata 中,有的立即数和指令编码放在 .text
  • 对于字符串常量,若程序中存在重复的字符串,编译器会保证只存在一个
  • .rodata 是在多个进程间共享的
  • 有的嵌入式系统,.rodata 放在 ROM(或者 NOR FLASH)中,运行时直接读取无需加载至 RAM。想要将数据放在 .rodata 只需要加上 const 属性修饰即可。

5、代码区

  • 程序执行代码存放在代码区,其值不能修改(若修改则会出现错误)。
  • 字符串常量和 define 定义的常量也有可能存放在代码区。

6、总结

下面已一段代码来看一下各部分存储:

#include <stdio.h>

static unsigned int val1 = 1;         // val1存放在.data段
unsigned int val2 = 1;                // 初始化的全局变量存放在.data段
unsigned int val3 ;                   // 未初始化的全局变量存放在.bss段
const unsigned int val4 = 1;          // val4存放在.rodata(只读数据段)

unsig
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值