c语言几个关于变量存储区域的问题----C语言内存管理----C语言内存分区

106 篇文章 8 订阅

在这里插入图片描述
https://blog.csdn.net/qq_40732350/article/details/117571947?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167054932116782425178352%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=167054932116782425178352&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-20-117571947-null-null.142v68control,201v4add_ask,213v2t3_control1&utm_term=C%E8%AF%AD%E8%A8%80%20%E5%8F%98%E9%87%8F%E5%A2%9E%E9%95%BF%E5%88%B0%E6%9C%80%E5%A4%A7%E5%80%BC%E8%87%AA%E5%8A%A8%E6%B8%85%E9%9B%B6&spm=1018.2226.3001.4187

STM32启动过程分析
1.1 STM32的程序在flash上的存储结构
在这里插入图片描述
1.2 STM32的数据在SRAM上的存储结构
在这里插入图片描述

Code是代码占用的空间;
RO-data是 Read Only 只读常量的大小,如const型;
RW-data是(Read Write) 初始化了的可读写变量的大小;
ZI-data是(Zero Initialize) 没有初始化的可读写变量的大小。ZI-data不会被算做代码里因为不会被初始化;(ZI是指zero-initialized)
简单的说就是在烧写的时候是FLASH中的被占用的空间为:Code + RO Data + RW Data
程序运行的时候,芯片内部RAM使用的空间为: RW Data + ZI Data

我在纳闷儿,上面的描述中为什么没有栈和堆的概念?因为上面描述的是程序运行前的内存分配,而堆和栈是程序运行时才分配空间的,而且堆和栈有专门的存储区域,
可执行文件在内存运行时由
栈**,数据段(由三部分部分组成:只读数据段(.rodata),已经初始化读写数据段(.data),未初始化数据段即BBS)和代码段组成,**

C语言的内存管理(代码段、数据段,栈,堆)

C语言程序分为映像和运行两种状态。
经过编译连接后形成的映像由:代码段(text) 数据段(data 包括RO data ,RW data), 其他段(调试的段,动态库共享库链接表的段)组成。
可执行文件在内存运行时由数据段(由三部分部分组成:只读数据段(.rodata),已经初始化读写数据段(.data),未初始化数据段即BBS)和代码段组成,如下图所示:
在这里插入图片描述
所以:数据区 = .rodata .data .bss
.rodata = 文字常量区
全局区和静态区指的是 .data 和 .bss区

https://blog.csdn.net/weixin_42108004/article/details/84581073?ops_request_misc=&request_id=&biz_id=102&utm_term=c%E8%AF%AD%E8%A8%80%E6%95%B0%E6%8D%AE%E6%AE%B5&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-1-84581073.pc_search_result_control_group&spm=1018.2226.3001.4187
在这里插入图片描述
原文链接:https://blog.csdn.net/weixin_39964178/article/details/82875304

C语言内存分区_栈区、堆区、全局&静态区、文字常量区、程序代码区

栈区:

在函数中定义的变量存放的内存区域。

常见的int、float、char等变量均存放于栈区中,它的特点是由系统自动分配与释放,不需要程序员考虑资源回收的问题,方便简洁。

ps:栈区的地址分配是从内存的高地址开始向地地址分配。

堆区:

程序员通过指令自主向系统申请的内存区域,大小由程序员决定,它在使用完后同样需要程序员通过指令去释放该区域内存,否则将有可能出现内存的浪费与溢出。

C语言中申请堆区指令为:

int *p = (int *) malloc( N * sizeof(int) ); //分配N个int型(4字节)的内存,即 4 * N 个字节

ps:但指针p存放于栈区。
C语言中释放堆区指令为:

free( p ); //注意此处参数为指针

使用中应该注意,尽量不要去修改p指针对应的地址值,否则在内存释放时将出现错误。(编译可通过,运行出现问题)

全局变量&静态变量区:

全局变量与静态变量本应是两个概念,但由于它们在内存中存放的区域相同,所以将他们放在一起讨论。

全局变量:

位于所有函数外部定义的变量,在整个工程中可见,可修改。

静态变量:

位于所有函数内部定义的由 static 修饰的变量,仅在定义的函数中可见,可修改。(这是它与全局变量的关键区别)

ps:静态变量仅在第一次创建时初始化一次,之后自动跳过初始化语句。

全局变量与静态变量均由系统分配和释放内存,若未对它们进行初始化操作,系统将自动将其值设置为0。(堆区与栈区则不会)

文字常量区:

用于存放文字等不可修改的常量,由系统分配和释放内存。

常见的使用:

char *s = “HelloWorld”;//该字符串 HelloWorld 即存放于文字常量区,不可修改

ps:但指针s存放于栈区。

pps:若在程序中尝试对其修改(例如尝试修改第一个字符 *s = ‘h’;),将出现编译可通过,运行报错的情况。

同时因注意它与const修饰的变量之间的区别:

char aa = ‘A’;//aa存放于栈区

const char bb = ‘B’; //bb同样存放于栈区

const修饰的变量仅仅用于告诉编译器bb是一个常量,如果后续的程序中有出现尝试修改bb的操作时,编译将报错。

这种写法主要是为了防止程序员在后续的代码中误操作bb变量而添加的一个约束条件,并不会影响它存放的位置。

程序代码区:
用于存储程序编译连接后生成的二进制机器码指令的内存区域。该部分内容可通过反汇编操作将机器码转换为汇编语言。

C语言分为五大内存分区:

1、栈区(stack): —由编译器自动分配释放,存放函数的参数值,局部变量的值等。
2、堆区(heap): 一般由程序员分配释放,若程序员不释放,程序结束时由系统释放。
3、全局区(静态区,static): 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。
4、文字常量区: 常量字符串就是放在这里的。程序结束后由系统释放。
5、程序代码区: 存放函数体的二进制代码。

注:全局变量&静态变量区:

全局变量与静态变量本应是两个概念,但由于它们在内存中存放的区域相同,所以将他们放在一起讨论。
全局变量:
位于所有函数外部定义的变量,在整个工程中可见,可修改。
静态变量:
位于所有函数内部定义的由 static 修饰的变量,仅在定义的函数中可见,可修改。(这是它与全局变量的关键区别)
ps:静态变量仅在第一次创建时初始化一次,之后自动跳过初始化语句。
全局变量与静态变量均由系统分配和释放内存,若未对它们进行初始化操作,系统将自动将其值设置为0。(堆区与栈区则不会)
原文链接:https://blog.csdn.net/Filter_CPH/article/details/48524249

学过C语言的应该都知道程序分区这个概念,只是可能不是那么的熟悉,下面就简要的谈论一下C程序的分区

比如在一个C程序中写一个i全局变量int a = 10;那么这个整形变量a存放在哪儿,又或者是函数中定义的,又该放在哪儿。

1、未初始化的全局变量和初始化为0的全局变量(.bss 段)

bss类型的全局变量只占运行时的内存空间,而不占用文件空间。存在于整个程序运行过程中。

2、初始化过且非零的全局变量(.data 段)

data类型的全局变量既占文件空间又占用运行时的内存空间。存在于整个程序运行过程中。

3、常量数据(.rodata 段)

常量不一定放在.rodata段,有的立即数与指令编码在一起放在.text 段中。

对于一个字符串常量,编译器会自动去掉重复的字符串,保证一个字符串在一个可执行文件中只存在一份复制。

.radata在多个进程间是共享的,提高运行空间利用率。

修改常量会出现段错误。

一些系统中会把rodata放在ROM中(或者NOR Flash),运行时直接读取,无需加载到RAM中。

4、代码(.text 段)

存放代码和部分整数常量,和.rodata段相似,主要不同的是这个段可以执行。

5、栈(stack)

可以用于实现函数的调用,管理临时变量。

栈向下增长。

6、堆(heap)

由程序员手动分配和释放的一块内存区域。

注意malloc、realloc、free的用法。这里不再详细讲解。

原文链接:https://blog.csdn.net/m0_37968915/article/details/72801134

1.初始化和未初始化的全局变量存储在哪个区域?

C规定,未初始化变量的初值为0,这个清0的操作是由启动代码完成的,还有已初始化变量的初值的设置,也是由启动代码完成的。
为了启动代码的简单化,编译链接器会把已初始化的变量放在同一个段:.data,这个段的映像(包含了各个变量的初值)保存在“只读数据段”,这样启动代码就可以简单地复制这个映像到 .data 段,所有的已初始化变量就都初始化了。
而未初始化变量也放在同一个段:.bss,启动代码简单地调用 memset 就可以把所有未初始化变量都清0。

一.初始化的全局变量存放在数据段(data segment),数据段数据静态分配

二.未初始化的全局变量存放在bss段,BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。
“未初始化”这一说法其实并不准确,虽然.bss段在编译出的目标文件中是不占 空间的,但是c语言假设在程序的执行之前,运行时启动代码或者操作系统会负责将.bss段清零,而且许多c语言都依赖这一特性。

三.BSS是英文Block Started by Symbol的简称

四.在编译后的目标文件中不占有空间

原文链接:https://blog.csdn.net/weiyuanke/article/details/7645129

2.例:char *A = “helloworld”;

问:A存储在呢个区域? 看A定义在函数内还是函数外
“helloworld”存储在那个区域? 文字常量区

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学无止境2022

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值