【STM32单片机入门-1】堆栈/全局变量,局部变量,静态全局变量,局部静态变量等

1,堆栈对比

堆:由程序员分配和释放。容易产生碎片,使用方便,地址分配使用从下到上

栈:用来存放函数地址和局部参数,主函数使用时,要对函数的首地址断点保存,地址分配从上到下,用完自动释放

  • 0x2001,0000往下是未用的空间,可以做栈空间,只要不破坏全局变量,地址由程序员配置

2,静态存储区/全局变量/全局静态变量

静态存储区:它主要存放静态数据、全局数据和常量。

全局变量:全局变量存放在静态存储区,作用域是全局,整个声明周期都可以使用,其他文件如需要使用,需要添加extern

全局静态变量 (static):分配的内存与全局变量一样,也是在静态存储内存上,其生命周期也是与整个程序同在的,从程序开始到结束一直起作用,

全局静态变量作用域只在定义它的一个源文件内,其他源文件不能使用它

相同点

是由编译器自动分配和释放的,

初始化的全局变量和静态变量放在同一块内存区中

在调用main之前,内存先从FASH copy 数据(全局/静态变量),和复制全0段的(全局/静态变量)

全局变量和静态变量从0x2000,000开始存

3,局部变量和局部静态变量

分配内存是分配在栈存储区上的,其作用域也只是在局部函数内,在定义该变量的函数内,只要出了该函数,该局部变量就不再起作用,该变量的生命周期也只是和该函数同在。

局部变量

在栈里,临时给a 分配空间,

局部静态变量

分配的内存也是在静态存储内存上的,其第一次初始化后就一直存在直到程序结束,该变量的特点是其作用域只在定义它的函数内可见,出了该函数就不可见了。

4,代码举例

volatile int a = 0;// 全局初始化区  ①存放在内存起始单元0x2000,0000 
volatile char *p1; //全局未初始化区 ②存放在起始单元00x2000,0004 
void test(void)
{
    volatile  int t1=10;   //局部变量                      ④存放在栈空间  0x2000,0600  
    volatile static int t2 =0;//局部静态变量          ③存放在起始单元0x2000,0008     
 //    printf("%d %d  ",t1,t2);//防止代码被优化
}
void main()
{
    
    volatile int b  = 0;                                      //栈       ⑥存放在栈空间  0x20000620
    volatile char s[] = "abc";                        // 栈                ⑤存放在栈空间  0x2000061C 
    volatile char *p2;                                      //栈          存放在堆空间  0x20000618 
    volatile char *p3 = "123456";               //123456\0在常量区,p3在栈上。 0x20000614  
    volatile static int c =0;              //局部(静态)初始化区 ④存放在起始单元00x2000,000c
    test();
    
    //分配得来得10和20字节的区域就在堆区。
     p1 = (char *)malloc(10);
     p2 = (char *)malloc(20);
    volatile char *p4= (char *)malloc(20);  //存放在堆空间 0x20000610
    strcpy(p2, "123456");                                 //123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
    
    printf("%d %d %d %d  %d %d  %d ",a,s[0],&p3,c,p1,b,&p2,&p4);//防止代码被优化
}

来自文心一言的解答

这段代码中的变量存储位置以及内存分配涉及到C语言的内存布局和内存管理。首先,我们逐一回答您的问题。

  1. t1存放在栈空间中,请问栈空间的起始地址在哪里配置的?

栈空间的起始地址和大小通常是在程序启动时由操作系统配置的。具体的配置方式依赖于操作系统和硬件架构。在嵌入式系统或低级编程中,可能会直接设置栈指针寄存器来指定栈的起始和结束位置。在高级操作系统中,如Linux或Windows,这通常是进程创建时的一部分自动管理。

2. p2,p3,p4 都是堆空间分配地址的吗?

p2p4 是通过 malloc 分配的,所以它们指向的地址是在堆空间中的。而 p3 是一个指向字符串常量 "123456" 的指针,这个字符串常量通常存放在程序的常量区,不是堆空间。

3. 这个地址位置也和栈在一个地址范围吗?

不一定。堆和栈通常是两个不同的内存区域,它们有自己的起始和结束地址。具体的位置和大小取决于操作系统、编译器设置和硬件架构。在某些架构和操作系统中,堆和栈可能是相邻的,但它们仍然是逻辑上分离的区域。

现在,关于代码中的内存布局:

ap1 是全局变量,它们存放在全局/静态存储区。

t1 是局部变量,存放在当前函数的栈帧中。

t2 是局部静态变量,存放在全局/静态存储区,但其生命周期局限于定义它的函数内。

b, s, p2, p3, 和 c 都是在 main 函数内的局部变量。其中,sb 存放在栈上;p2p3 本身存放在栈上,但它们通过 malloc 分配的内存位于堆上;c 是局部静态变量,存放在全局/静态存储区。

p4 也是一个局部变量,存放在栈上,但通过 malloc 分配的内存位于堆上。

请注意,具体的内存地址(如0x2000,0000、0x2000,0004等)在代码中只是示例,实际运行时可能会有所不同。另外,当您提到 "防止代码被优化" 时,使用 volatile 和打印变量的方式确实可以防止某些编译器优化,但这不是一个通用的或推荐的方法。更好的方法是使用适当的编译器优化设置和/或编译器特定的属性或注解来确保代码的正确性和性能。

5,总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/260746.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微软官方发布的C#开源、免费、实用的Windows工具箱

前言 今天分享一款由微软官方发布的C#开源、免费、实用的Windows工具箱(帮助用户调整和简化Windows系统的体验,从而提高工作效率):Microsoft PowerToys。 项目介绍 Microsoft PowerToys 是使用 C 和 C# 编程语言开发的。它利用了 …

ansible的playbook

1、playbook的组成部分 (1)task任务:在目标主机上执行的操作,使用模块定义这些操作,每个任务都是一个模块的调用 (2)variables变量:存储和传递数据(变量可以自定义&…

DRF从入门到精通二(Request源码分析、DRF之序列化组件)

文章目录 一、Request对象源码分析区分原生request和新生request新的request还能像原来的reqeust一样使用吗源码片段分析总结: 二、DRF之序列化组件序列化介绍序列化步骤序列化组件的基本使用反序列化基本使用反序列化的新增反序列化的新增删除单条 反序列化的校验 …

天猫数据分析(天猫查数据工具):2023年天猫平台假发行业市场销售数据分析报告

如今,由于人们工作和生活的压力较大,居民脱发问题严重,且脱发群体倾向于80后和90后,逐渐向低龄化发展。除脱发外,在颜值经济的背景下,人们越来越注重外貌和形象,假发作为一种改善发型的工具&…

Graylog配置日志保留策略

找了半天没找到说的清楚的,只能抠官方文档 graylog的归档(日志持久化)只有付费版才能用,所以日志只能存在es中 1.理解官方给出的几个概念 轮转策略 (Index Rotation Strategy): 轮转策略定义了何时创建新的索引以及何时关闭旧的索…

ssm基于vue技术的绿色蔬菜销售管理系统+vue论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本绿色蔬菜销售管理就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息…

网络技术基础与计算思维实验教程_2.2_单交换机实验_重制版

实验内容 实验目的 实验原理 关键命令说明 开始实验 构建 选择交换机 选择终端--台式机 放置四台终端 直通线连接 依次连接pc0到pc3 终端配置Ip地址和子网掩码 完成了交换机和终端连接以后,为每一个终端配置Ip地址和子网掩码 单击pc0 在选择桌面选项卡中选择Ip配置使用程序 …

快速从图中提取曲线坐标数据的在线工具WebPlotDigitizer

快速从图中提取曲线坐标数据的在线工具WebPlotDigitizer 1 介绍2 WebPlotDigitizer在线版的使用2.1 上传图像2.2 点击横纵坐标点:2.3 选择曲线 3 查看数据参考 1 介绍 写论文时要对比别人曲线图、点图、柱形图的数据,但是只有图没有原始数据怎么办&…

【51单片机系列】C51中的中断系统扩展实验

本文是关于51单片机中断系统的扩展实验。 文章目录 一、 扩展实验一:使用外部中断0控制蜂鸣器,外部中断1控制直流电机二、扩展实验二:修改定时器初值,设定3秒钟的定时时间让LED模块闪烁三、扩展实验三:使用定时器1和数…

基于NestJS 和 TypeORM 实现 CURD RESTful API接口

前言 对于服务端项目而言,对外如何提供合格规范的HTTP接口,对内如何优雅的操作数据存储,比如mysql、mongodb。 本文是NestJS服务端开发的基础入门教程,我会根据成熟的解决方案,给大家详细介绍如何基于NestJS实现开发…

【RTOS学习】源码分析(信号量和互斥量 事件组 任务通知)

🐱作者:一只大喵咪1201 🐱专栏:《RTOS学习》 🔥格言:你只管努力,剩下的交给时间! 目录 🍓信号量和互斥量🍅创建🍅Take🍅Give &#x…

中国激光雷达的2023:倔强的笨小孩

作者 |David 编辑 |王博 现在回头来看,从2007年莱万多夫斯基和大卫霍尔在硅谷骑着摩托车四处兜售激光雷达开始,到2023年仅中国车载市场出货量接近60万,覆盖了市面上40%以上搭载高阶智驾的新车型,激光雷达一直在用有力的数据回应着…

华为atlas300安装教程

1、安装包位置: /data/ai_install_packages 2、添加HwHiAiUser用户: groupadd -g 1000 HwHiAiUser useradd -g HwHiAiUser -u 1000 -d /home/HwHiAiUser -m HwHiAiUser -s /bin/bash 3、安装驱动: ./Ascend-hdk-310p-npu-driver_6.0.0_l…

HashMap扩容是2倍的原因(全网博客几乎都解释错了)

零、前言 最近在写博客时,突然又想起来哪个经常出现在面试题里的问题: HashMap扩容为什么是原来的2倍? 因为看过源码,我觉得这个问题并不难。在我之前的通俗解释equals和hashCode的关系和作用里也说过这个原因。但为了博客的严谨…

DesignDoll使用方法

选择材质球 取消网格线 控制手部动作-设置左右手 - 手部运动 控制身材 控制身高 比例

第三节TypeScript 基础类型

1、typescript的基础类型 如下表: 数据类型 关键字 描述 任意类型 any 生命any的变量可以赋值任意类型的值 数字类型 number 整数或分数 字符串类型 string 使用单引号(‘’)或者双引号(“”)来表示字符串…

RESTful简介与C/C++实现

一、RESTful简介 RESTful,全称为Representational State Transfer,是一种软件架构风格和设计理念,而不是一种标准。它主要用于Web服务的设计和开发,强调资源的状态表示和状态转移。RESTful风格的设计使得Web服务更加简洁、清晰和…

页面菜单,通过get请求一个url后,跳转另外一个页面,+丢失问题

业务场景描述: 在A系统,菜单点击跳B系统这个操作。 A系统菜单是get请求到B系统的一个缓冲页面,然后这个缓冲页面获取到url中的accessToken后,在这个页面中通过post请求后端接口。 问题描述: 当accessToken中包含了…

MongoDB 单机安装部署

文章目录 说明1. 下载安装包2. 安装数据库3. 配置 systemctl4. 创建 root 用户 说明 本篇文章介绍 MongoDB 二进制安装的步骤,整个过程还是比较简单。 1. 下载安装包 进入 MongoDB 官网,获取安装包的下载链接: https://www.mongodb.com/tr…

Leetcode—179.最大数【中等】

2023每日刷题&#xff08;六十五&#xff09; Leetcode—179.最大数 算法思想 实现代码 其中sort的lambda自定义排序策略参考自官方文档 class Solution { public:string largestNumber(vector<int>& nums) {string ans;vector<string> strs;for(auto num: …
最新文章