当前位置: 首页 > news >正文

c语言笔记 静态数据与ELF程序格式

数据段:

1.全局变量   
2.常量.rodata段
3.已初始化的静态数据(全局变量).data段
4.未初始化的静态数据(static修饰的局部变量).bss段

为什么需要静态数据?

  1. 全局变量 可以在任何文件,函数中使用,数据操作上更加方便。
  2. static修饰的局部变量,在函数中一直保存着,这可以使用static来保存某些重要的数据,使其运算后不消失,以便下次使用的时候。
注意:
  1. 静态数据只会被初始化一次;
  2. 如果静态数据未写初始化的值会默认为0;
  3. 静态数据的生命周期很长,会随着程序的结束才消失;
  4. 被static修饰的局部变量会从运行栈中移动到数据段;
  5. 被static修饰的全局变量变成仅有本文件可见静态数据;
  6. 被static修饰的函数由各文件可见,变成本文件可见的静态函数。

静态局部变量的问题:如果我定义一个全局变量a 然后我又在函数内定义一个局部变量a值,那么我会先使用哪一个a?

在编程中,如果全局变量和局部变量同名,那么在函数内部会优先使用局部变量。也就是说,你在函数内定义的局部变量 a 会遮蔽全局变量 a,函数内使用的将是局部变量 a。
  1. 全局变量:在函数外部定义的变量 a,作用域是全局的,可以在函数外部和内部访问。
  2. 局部变量:在函数内部定义的变量 a,作用域仅限于函数内部。
  3. 优先级:在函数内部,局部变量的优先级高于全局变量。如果函数内部定义了与全局变量同名的局部变量,那么在函数内部会使用局部变量,而不会使用全局变量。

代码段:

  1. 用户代码 .text
  2. 系统初始化代码 .init
程序员的代码,所有的静态数据以及代码编译完之后会在硬盘内放着,那些局部变量,形参,malloc()出来的堆内存,栈内存在我们的硬盘ELF可执行文件里面是没有,栈内存和堆内存都是存放在虚拟内存空间。而虚拟内存里面是数据段和代码段是对硬盘ELF可执行文件里面的数据段和代码段的复制。
也就是硬盘ELF里面的数据段和代码段直接复制到虚拟内存空间。
数据段和代码段都是在编译时编译完成时候就存在的。不是运行时就存在,在数据段和代码段这些内容编译完后,再运行到我们的虚拟内存.在时间上ELF可执行文件会比虚拟内存空间更早获得数据段和代码段。(ELF是一个二进制文件)
图片关系:

1. 程序员的代码和静态数据

  • 硬盘中的ELF可执行文件
程序员编写的代码和静态数据(如全局变量、静态变量等)在编译和链接后会生成一个ELF格式的可执行文件。这个文件存储在硬盘上。
  • 虚拟内存空间
当程序运行时,操作系统会将ELF可执行文件中的代码段和数据段加载到虚拟内存空间中。这些段在程序运行时被映射到虚拟地址空间中。

2. 局部变量、形参、堆内存和栈内存

  • 局部变量和形参
这些变量存储在栈内存中。栈内存是运行时动态分配的,用于存储函数调用时的局部变量和参数。栈内存的分配和释放是由编译器自动管理的。
  • 堆内存:
通过malloc()等函数分配的内存存储在堆中。堆内存是运行时动态分配的,需要程序员手动释放。
  • 栈内存和堆内存
这些内存区域是在程序运行时由操作系统分配的,而不是在编译时确定的。它们不在ELF可执行文件中,而是在程序运行时由操作系统管理。

3. 虚拟内存空间

  • 虚拟内存
虚拟内存是操作系统提供的一种内存管理机制,它将物理内存和磁盘空间结合起来,为每个进程提供一个独立的地址空间。
  • 数据段和代码段
ELF可执行文件中的数据段(.data、.bss等)和代码段(.text)在程序运行时被映射到虚拟内存空间中。这些段在编译时就已经确定,但在程序运行时才被加载到内存中。

4. 时间顺序

  • ELF可执行文件
在编译和链接阶段生成,存储在硬盘上。它包含程序的代码段和数据段。
  • 虚拟内存空间
在程序运行时由操作系统分配和管理。数据段和代码段从ELF文件中加载到虚拟内存空间中,而栈内存和堆内存则在运行时动态分配。

总结

  • ELF可执行文件
编译时生成,存储在硬盘上,包含代码段和数据段。
  • 虚拟内存空间
运行时分配,包含从ELF文件加载的代码段和数据段,以及运行时动态分配的栈内存和堆内存。
  • 栈内存和堆内存
运行时动态分配,不在ELF文件中。
可以说程序在运行的时候ELF提供数据段和代码段。

相关文章:

  • 关于C/C++语言的初学者在哪刷题,怎么刷题
  • 在资源有限中逆势突围:从抗战智谋到寒门高考的破局智慧
  • SpringMVC-全局异常处理
  • 程序化广告行业(2/89):从程序化广告深挖数据处理技巧
  • linux下文件读写操作
  • 【YOLOv8】YOLOv8改进系列(5)----替换主干网络之EfficientFormerV2
  • linux 软件安装(中)
  • JSONUtil InvocationTargetException: null
  • vscode带参数调试
  • jdk-21_linux-x64_bin.tar.gz Linux jdk21压缩包安装保姆级(详细安装教程)
  • 【AI】让deepseek_r1 671b将draw.io对应的xml数据格式转换成markdown上可以直接渲染出来的Mermaid格式
  • LSTM方法实践——基于LSTM的汽车销量时序建模与预测分析
  • 车载以太网测试-4车载以太网如何进行通信的?
  • 高级java每日一道面试题-2025年2月18日-数据库篇-MySQL 如何做到高可用方案?
  • Postgresql安装
  • 多模态融合的分类、跨模态对齐的方法
  • Spring boot创建时常用的依赖
  • flask_restx 定义任意类型参数
  • MySQL主从延迟分析
  • JVM、MySQL常见面试题(尽力局)
  • 上海一保租房社区亮相,首批546套房源可拎包入住
  • 2025年“新时代网络文明公益广告”征集展示活动在沪启动
  • 韧性十足的中国外贸企业:“不倒翁”被摁下去,还会再弹起来
  • 伊朗最高领袖顾问:伊朗愿承诺永不制造核武,换取美解除制裁
  • 中央宣传部、全国妇联联合发布2025年“最美家庭”
  • 男子不满和睦家医院手术效果还遇到了“冒牌医生”?院方回应