【Linux】程序地址空间回顾

我们的地址空间划分成如下几个区域:

代码区,字符常量区,已初始化全局变量区,未已初始化全局数据区,堆区,栈区;其中有代码区至栈区的代码地址依次增大。

局部变量是具有临时性的局部变量,在栈上开辟

我们在C,C++上malloc时候申请的叫做堆空间,是在堆区开辟的。

我们平时那么定的全局变量可以对所有的函数访问,是因为全局变量在全局数据区

请问,在这个图当中,我们所展示的这个东西,它是内存吗?

答案是:不是,这个东西其实是地址空间,C,C++程序是以这样的方式分布的。


验证地址空间的增长方向

①首先我们要打印的一个区域的代码区:

现在要打代码的地址,可是我们要以谁做为我们对应的代码区呢?

在我们整个的代码当中,我们就有一个叫做main函数的函数,其中函数名代表的就是它的地址

我们用main函数充当我们代码区的地址,所以代码区的地址我们就有了:

②字符常量序区,那么需要有个字符常量:

那么告诉我%p这里我们在输出的时候,那么是需要输出的是str呢?还是&str呢?还是*str呢?

那么很显然,我们要打的是这个字符串常量,它的起始地址在str变量里面。字符指指针变量也是变量,它里面保存的就是这个字符串的起始地址,所以打印str就行了

③我们要打印已初始化全局变量和未初始化变量:

在main函数外定义两个全局变量,如图:

打印:

④我们要打印堆区:

请问这次在打印时打印的是men还是&men呢?

答案是:men,因为要打印的是堆它对应的地址;

⑤打印栈的地址:

那么我们栈区的变量在哪呢?

我们在函数当中定义的变量叫做局部或者临时变量,调用函数时形成该变量,函数返回时该变量被释放。

那么为什么呢?
因为调用函数时,我们需要在栈上为该函数申请,我们对应的栈空间的。
那么同样的,main函数也是函数。所以之前定义的str,men都是局部变量,局部变量在我们对应的栈上。

所以我们这里取地址是这样。

所以整个代码:

运行打印:

我们可以看到它就在这里依次向上增长



脑子里只要有这张图。
我们就知道 c语言当中全局变量,局部变量还有很多变量,那么它为什么那么最终临时变量就临时性呢?全局变量为什么一直有效?原因我们就能清楚了。

其中我们要知道栈区,它是向地址减少方向增长,向下增长。
而我们的堆区,它是向地址增大方向增长,也就是堆栈相对而生


验证栈,堆地址的增长方向:

验证栈的增长方向:

打印结果:

那么为什么是向地址减少的方向增长呢?
因为栈向地址减小方向增长,先定义的变量,先入栈,后定义变量后入栈,所以它的地址当然会小。

验证堆空间:

打印结果:

你会发现堆和栈它两个的地址差别很大,它两个之间有一大段的镂空。那么这段镂空是什么?我们后面讲动静态库的时候再说。反正呢,那么堆栈是相对而生的。我们这么理解就OK了来。


验证关于static的语法问题

我们知道全局变量它会一直存在,并不随着一个函数的调用和返回,这个全局变量不会释放。那么这就说明,不论是你初始化还是未初始化,只要是全局变量,这个区域我们统称为全局数据区。

在学c语言的时候,我们有一种变量叫做static,那么把我们对应的一个变量用static这个来进行修饰。

static并不会随着这个函数的使用完毕而释放,它只做一次初始化,首次调制函数是初始化。往后它就直接使用这个变量。这个函数它的生命周期就不随着函数的调用和释放,或者是返回这个变量就不会释放了。

问题是,为什么我们用static这个变量一修饰这个a,那么它就不会被释放了呢?

打印结果:

对比全局变量:

说明我们对应的static修饰的叫做局部变量,编译的时候已经被编译到全局数据去了,所以它才不会随着你函数的调用,然后去自动释放的,因为它已经是一种全局变量了。

只不过它是那么身在曹营,身不由己。
static在一个函数代码块里,所以它只能在这个代码块里面被使用,这叫做这个变量,作用域只能在函数里面但是它的生命周期已经是全局了

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Danswer 接入 Llama 2 模型 | 免费在 Google Colab 上托管 Llama 2 API

一、前言 前面在介绍本地部署免费开源的知识库方案时,已经简单介绍过 Danswer《Danswer 快速指南:不到15分钟打造您的企业级开源知识问答系统》,它支持即插即用不同的 LLM 模型,可以很方便的将本地知识文档通过不同的连接器接入到…

fpga时序相关概念与理解

一、基本概念理解 对于数字系统而言,建立时间(setup time)和保持时间(hold time)是数字电路时序的基础。数字电路系统的稳定性,基本取决于时序是否满足建立时间和保持时间。 建立时间Tsu:触发器…

pytorch_神经网络构建5

文章目录 生成对抗网络自动编码器变分自动编码器重参数GANS自动编码器变分自动编码器gans网络Least Squares GANDeep Convolutional GANs 生成对抗网络 这起源于一种思想,假如有一个生成器,从原始图片那里学习东西,一个判别器来判别图片是真实的还是生成的, 假如生成的东西能以…

大数据毕业设计选题推荐-家具公司运营数据分析平台-Hadoop-Spark-Hive

✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

测试用例的设计方法(全):错误推测方法及因果图方法

目录 错误推测方法 一. 方法简介 因果图方法 一. 方法简介 二. 实战演习 错误推测方法 一. 方法简介 1. 定义:基于经验和直觉推测程序中所有可能存在的各种错误, 从而有针对性的设计测试用例的方法。 2. 错误推测方法的基本思想: 列举出程序中…

socks5代理和https代理有什么不同?各自有哪些优点?

socks5代理和https代理是两种不同的代理服务,它们在实现方式、安全性和协议特点等方面存在差异。下面我们来详细了解一下这两种代理的优点。 一、socks5代理的优点 1. 速度快 socks5代理采用了TCP协议,能够有效地减少网络延迟和数据传输速度慢的问题&…

Vue 传参踩坑之旅——事件总线与 props

Vue 传参踩坑之旅——事件总线与 props 缘由 今天突然发现项目出现了一个 bug,这里简单描述一下。 这里有 A、B、C、D 四个组件,关系为 A - 祖先、B - 父、C - 子、D - 叔(实际业务组件关系复杂很多)。 A - 祖先 B - 父 C - 子…

海思SD3403/SS928开发板 开发记录二: 设置网络 telnet连接开发板

1.设置网络 设置桥接网络 并修改虚拟机IP网段 问题1.参照前一篇博客 2.ping 测试 主机 虚拟机 板端 相互通信 3.telnet 登录板端

解决 win11 vmware 中centos 网络不能访问外网

解决 win11 vmware 中centos 网络不能访问外网 1、进入win11 高级设置,找到centos 虚拟机使用的网卡 2、看网卡的其他属性 3、按照红圈部分,配置成一样的就行 4、进入到虚拟机配置中,配置成如图一样的NAT模式 5、再进入编辑 -》虚拟网络编辑…

ros1 自定义订阅者Subscriber的编程实现

话题模型 图中,我们使用ROS Master管理节点。 有两个主要节点: Publisher,名为Turtle Velocity(即海龟的速度)Subscriber,即海龟仿真器节点 /turtlesim Publisher(Turtle Velocity),发布Messa…

Leetcode刷题详解——子集

1. 题目链接:78. 子集 2. 题目描述: 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1: 输入&#xf…

​软考-高级-信息系统项目管理师教程 第四版【第17章-项目干系人管理-思维导图】​

软考-高级-信息系统项目管理师教程 第四版【第17章-项目干系人管理-思维导图】 课本里章节里所有蓝色字体的思维导图