Ubuntu、stm32下的C程序中堆、栈、全局、局部等变量的内存分配

本文详细探讨了在Ubuntu和STM32环境下C程序的内存分布,包括栈区、堆区、全局区(.bss段、.data段)、常量区和代码区的特征和内存管理。通过编程验证,分析了不同系统中栈和堆地址的变化规律,并引用Keil的内存段划分进一步解释了内存分配。最后总结了理解这些知识对于优化程序的重要性。
摘要由CSDN通过智能技术生成

一、内存分布

1、地址详解

在一个STM32程序代码中,从内存高地址到内存低地址,依次分布着栈区堆区全局区(静态区)常量区代码区,其中全局区中高地址分布着.bss段,低地址分布着.data段。
总分布如下:

内存高地址 栈区
堆区
.bss段
.data段
常量区
内存低地址 代码区

1)栈区

  • 临时创建的局部变量存放在栈区。

  • 函数调用时,其入口参数存放在栈区。

  • 函数返回时,其返回值存放在栈区。

  • const定义的局部变量存放在栈区。

2)堆区

  • 堆区用于存放程序运行中被动态分布的内存段,可增可减。

  • 可以有malloc等函数实现动态分布内存。

  • 有malloc函数分布的内存,必须用free进行内存释放,否则会造成内存泄漏。

3)全局区(静态区)
全局区有.bss段和.data段组成,可读可写。

4).bss段

  • 未初始化的全局变量存放在.bss段。

  • 初始化为0的全局变量和初始化为0的静态变量存放在.bss段。

  • .bss段不占用可执行文件空间,其内容有操作系统初始化。

5).data段

  • 已经初始化的全局变量存放在.data段。

  • 静态变量存放在.data段。

  • .data段占用可执行文件空间,其内容有程序初始化。

  • const定义的全局变量存放在.rodata段。

6)常量区

  • 字符串存放在常量区。

  • 常量区的内容不可以被修改。

7)代码区

  • 程序执行代码存放在代码区。

  • 字符串常量也有可能存放在代码区。

2、数据存放位置

  • RAM(随机存取存储器)

存储的内容可通过指令随机读写访问。RAM中的存储的数据在掉电是会丢失,因而只能在开机运行时存储数据。其中RAM又可以分为两种,一种是Dynamic
RAM(DRAM动态随机存储器),另一种是Static
RAM(SRAM,静态随机存储器)。栈、堆、全局区(.bss段、.data段)都是存放在RAM中。

  • ROM(只读存储器)

只能从里面读出数据而不能任意写入数据。ROM与RAM相比,具有读写速度慢的缺点。但由于其具有掉电后数据可保持不变的优点,因此常用也存放一次性写入的程序和数据,比如主版的BIOS程序的芯片就是ROM存储器。代码区和常量区的内容是不允许被修改的,所以存放于ROM中。

二、编程验证

1)代码添加
首先,分别在Ubuntukeil中创建文件添加代码如下:

#include <stdio.h>
#include <stdlib.h>
//定义全局变量
int init_global_a = 1;
int uninit_global_a;
static int inits_global_b = 2;
static int uninits_global_b;
void output(int a)
{
   
	printf("hello");
	printf("%d",a);
	printf("\n");
}

int main( )
{
      
	//定义局部变量
	int a=2;
	static int inits_local_c=2, uninits_local_c;
    int init_local_d = 1;
    output(a);
    char *p;
    char str[
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值