C语言程序的内存布局

C语言中的内存模型 近来学习深觉自己在语言的底层方面理解欠缺, 正好之前有看过一点内存模型相关的文章, 正好就花点时间研究一下这方面相关的知识。以此文整合一下自己学到的知识, 文章中有错误或不足之处还请师傅们斧正。重点讲堆栈与堆区两个动态区的概念, 简单分析其中的区别和各自的优势。 阅读详情

C语言程序的内存布局

章介绍C语言程序的内存布局结构,包括连接过程中目标程序各个段的组成和运行过程中各个段加载的情况。

在本章的学习中,读者应重点关注以下内容:

C语言程序在内存中各个段的组成

C语言程序连接过程中的特性和常见错误

C语言程序的运行方式

13.1  C语言程序的存储区域

由C语言代码(文本文件)形成可执行程序(二进制文件),需要经过编译-汇编-连接三个阶段。编译过程把C语言文本文件生成汇编程序,汇编过程把汇编程序形成二进制机器代码,连接过程则将各个源文件生成的二进制机器代码文件组合成一个文件。

C语言编写的程序经过编译-连接后,将形成一个统一文件,它由几个部分组成。在程序运行时又会产生其他几个部分,各个部分代表了不同的存储区域:

1.代码段(Code或Text)

代码段由程序中执行的机器代码组成。在C语言中,程序语句进行编译后,形成机器代码。在执行程序的过程中,CPU的程序计数器指向代码段的每一条机器代码,并由处理器依次运行。

2.只读数据段(RO data)

只读数据段是程序使用的一些不会被更改的数据,使用这些数据的方式类似查表式的操作,由于这些变量不需要更改,因此只需要放置在只读存储器中即可。

3.已初始化读写数据段(RW data)

已初始化数据是在程序中声明,并且具有初值的变量,这些变量需要占用存储器的空间,在程序执行时它们需要位于可读写的内存区域内,并具有初值,以供程序运行时读写。

4.未初始化数据段(BSS)

未初始化数据是在程序中声明,但是没有初始化的变量,这些变量在程序运行之前不需要占用存储器的空间。

5.堆(heap)

堆内存只在程序运行时出现,一般由程序员分配和释放。在具有操作系统的情况下,如果程序没有释放,操作系统可能在程序(例如一个进程)结束后回收内存。

6.栈(stack)

栈内存只在程序运行时出现,在函数内部使用的变量、函数的参数以及返回值将使用栈空间,栈空间由编译器自动分配和释放。

C语言目标文件的内存布局如图13-1所示。

              图13-1  C语言目标文件的内存布局

 

代码段、只读数据段、读写数据段、未初始化数据段属于静态区域,而堆和栈属于动态区域。代码段、只读数据段和读写数据段将在连接之后产生,未初始化数据段将在程序初始化的时候开辟,而堆和栈将在程序的运行中分配和释放。

C语言程序分为映像和运行时两种状态。在编译-连接后形成的映像中,将只包含代码段(Text)、只读数据段(RO Data)和读写数据段(RW Data)。在程序运行之前,将动态生成未初始化数据段(BSS),在程序的运行时还将动态形成堆(Heap)区域和栈(Stack)区域。

一般来说,在静态的映像文件中,各个部分称之为节(Section),而在运行时的各个部分称之为段(Segment)。如果不详细区分,可以统称为段。

知识点:C语言在编译和连接后,将生成代码段(Text)、只读数据段(RO Data)和读写数据段(RW Data)。在运行时,除了以上三个区域外,还包括未初始化数据段(BSS)区域和堆(Heap)区域和栈(Stack)区域。

 

 

(1)静态存储:静态分配是一种最简单、最原始,同时也是一种最安全的分配方式,采用这种方式分配的变量,在程序进行编译的时候,就获得了一个唯一而且不变的存储空间,就好比是“从单位分到了房子”。正是因为这种分房子的策略,程序在编译的时候,“变量总共需要多少空间”,“现有的空间够不够”,“变量应该放在什么地方”,这些问题的答案从一开始就是明确的。一旦出现空间不足的情况,编译器会立即向我们报告。C语言中,所以得全局变量和静态的局部变量采用的都是静态分配的。

(2)栈式分配。利用栈后入先出的特点,栈式分配主要被用于局部变量的空间分配。这种好比“出租房”的分配策略,能在最大程度上提高存储空间的使用效率---某个函数被调用时,局部变量会从软件堆栈中获得一个存储空间;当函数退出时,该函数局部变量所占用的空间就又被释放出来以供他用。正是因为栈式分配的存在,使递归函数称为可能。

(3)堆式分配:堆式一个相对复杂的数据结构。本书不做讨论。我们需要知道的是,堆能够随意按照我们的需求将一块完整的奶酪一般“切出”我们所申请的份额。当这一空间不再有用,需要释放这一空间时,我们就归还这块“奶酪”。系统会在此时试图将几块彼此相邻的小“奶酪”拼接成一块较大的“奶酪”。正是因为这种方式的灵活性,堆式分配是我们构建复杂数据结构的常用手段。

C语言内存精讲,让你彻底明白C语言的运行机制! (先打开一个程序在计算机中到底是如何运行的.html) 2. 虚拟内存到底是什么?为什么我们在C语言中看到的地址是假的? 3. 虚拟地址空间以及编译模式 4. C语言内存对齐,提高寻址效率 5. 内存分页机制,完成虚拟地址的映射 6. 分页机制究竟是如何实现的? 7. MMU部件以及对内存权限的控制 8. Linux下C语言程序的内存布局(内存模型) 9. Windows下C语言程序的内存布局(内存模型) 10. 用户模式和内核模式 11. 栈(Stack)是什么?栈溢出又是怎么回事? 12. 一个函数在栈上到底是怎样的? 13. 函数调用惯例(Calling Convention) 立即下载

相关推荐

用KalmanNet搞定非线性状态估计:当卡尔曼滤波遇上神经网络

本文深入探讨了KalmanNet如何将神经网络与卡尔曼滤波结合,以解决非线性状态估计中的模型失配和噪声不确定性问题。通过保留经典滤波框架并用RNN学习卡尔曼增益,该方法在无人机导航、机器人定位等场景中实现了模型驱动与数据驱动的优势互补,提升了估计的鲁棒性和灵活性。

mango的博客 310

一个C程序运行时的内存分配情况

先把内容贴上来,没研究,留以后查看 //test.cint g_var_a=0;         //存放在全局已初始化数据区             char g_var_b; //存放在BSS区(未初始化全局变量)int main(){    int var_a; //存放在栈区

jasonwang的专栏 1527

博客系统 - 系统简介与首页设计

用Bootstrap实现手机端的博客导航栏效果。

m0_53450409的博客 1237

Linux下C语言程序的内存布局(内存模型)

以下内容源于C语言中文网的内容学习与整理,如有侵权请告知删除。

主要记录嵌入式学习与开发过程。 1702

Windows版本Carla(含RoadRunner插件)源码安装+RoadRunner地图导入

通过跳转浏览器账号密码登录github,不要选择Fine-grained personal access tokens,在git clone时会显示非授权,也不要使用Windows凭据!核心指令:编译PythonAPI–make PythonAPI,,编译Server–make launch,封装”游戏“–make package。完成安装后,在已安装->2022版本右侧->更多->导入配置,选择配置文件(需将配置文件内容更新为手册内容,如下图)->详细信息,更新。不要修改版本,执行上面指令即可!

winnizap的博客 1467

Ollama模型路径迁移实战:Windows/Mac/Linux三平台保姆级教程(附常见问题排查)

本文提供了一份详细的Ollama模型路径迁移教程,涵盖Windows、macOS和Linux三大平台。通过设置OLLAMA_MODELS环境变量或创建符号链接,指导用户将模型从默认路径安全迁移至新位置,以释放系统盘空间或提升性能。教程包含迁移前的准备、分平台步骤、迁移后的验证以及常见问题排查,确保迁移过程平滑可靠。

js777的博客 1184

Linux、Windows下C语言内存布局(内存模型)

Linux、Windows下C语言内存布局(内存模型) 在虚拟地址空间及编译模式中提到,虚拟地址空间在32位环境下大小为4GB,在64位环境下大小为256TB,那么,一个C语言程序的内存在整个地址空间中是如何分布的呢?数据在哪里?代码在哪里?为什么要这样分布? 内核空间和用户空间 对于32位环境,理论上程序可以拥有4GB的独立空间,我们在C语言中使用到的变量、函数、字符串等都会对应内存中的一块区域。 但是,在这4GB的地址空间中,要拿出一部分给操作系统内核使用,应用程序无法直接访问这一段内存,这一部分内存地

jayer的博客 4847

大模型——Ollama简明教程

在这篇文章中,我们将了解如何使用 Ollama、如何在 Ollama 中创建自己的模型 以及如何使用 Ollama 构建聊天机器人。这是深入研究 Ollama 的第一部分,以及我所学到的有关本地 LLM 的知识以及如何将它们用于基于推理的应用程序。在这篇文章中,你将了解——

1692

C 程序的内存布局

例如,由 C 中的 char s[] = “hello world” 定义的全局字符串和 main 之外的诸如 int debug=1 的 C 语句(即全局)将存储在初始化的读写区域中。该段中的数据在程序开始执行之前由内核初始化为算术 0,未初始化的数据从数据段的末尾开始,包含所有初始化为零或源代码中没有显式初始化的全局变量和静态变量。通常,文本段是可共享的,因此对于频繁执行的程序(例如文本编辑器、C 编译器、shell 等),只需要在内存中保存一个副本。

luoganttcc的博客 1013

什么是 SAP ABAP AMDP?

SAP HANA是SAP开发的一种内存数据库管理系统,它具有出色的性能和处理大规模数据的能力。为了充分利用SAP HANA的性能,SAP引入了AMDP技术,以便将数据库操作推送到数据库服务器执行,从而减少数据传输和处理时间。AMDP方法通常需要输入参数和输出参数。输入参数用于传递数据到SQLScript代码,而输出参数用于接收SQLScript代码的结果数据。ENDMETHOD.ENDCLASS.我们定义了一个输入参数来传递销售订单数据,以及一个输出参数来接收计算结果。ENDMETHOD.

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 908

chromium通信系统-ipcz系统(二)-ipcz系统代码实现-同Node通信

在chromium通信系统-mojo系统(一)-ipcz系统基本概念一文中我们介绍了ipcz的基本概念。 本章我们来通过代码分析它的实现。 handle系统 为了不对上层api暴露太多细节,实现解耦,也方便于传输,ipcz系统使用handle表示一个对象,handle类似于文件描述符,用IpczHandle类型表示ipcz系统内的一个对象。一个可以用IpczHandle 句柄表示的对象必须是APIObject子类。APIObject数据结构如下 class APIObject : public RefCou

woai110120130的专栏 1775

C语言程序内存布局

一、几个概念 1.栈(stack)       C语言通过栈来维护函数调用上下文,也就是说C中的函数、函数参数列表、局部变量、函数返回值都保存在栈内存中,在完成函数调用之后栈帧随即销毁,至于具体的压栈顺序和上下文维护工作由谁来完成,则取决于函数的调用方式(cdecl/stdcall/fastcall/pascal).       栈帧一般包括如下几方面内容:       ①函数的参数列表和

super_bert的专栏 4874

基于STM32L4XX 、HAL库的TMP144YFFR数字温度传感器驱动应用C语言程序设计

define TMP144_ADDRESS 0x00 // 默认为全局地址,用于单器件或MDA命令。#define TMP144_CMD_READ_TEMP 0x00 // 读取温度寄存器命令。if (temp_raw & 0x800) { // 判断第11位(符号位)

PP_Cottage的博客 91

浅谈C语言程序在Linux下的内存布局

浅谈C语言程序在Linux下的内存布局 ​ 在了解内存布局前,先要了解程序的虚拟地址空间以及编译模式。 ​ 所谓的虚拟空间,就是程序可以使用的虚拟地址的有效范围。虚拟地址和物理地址的映射关系由操作系统决定,相应地,虚拟地址空间的大小也由操作系统决定,但还会受到编译模式的影响。 ​ 先了解CPU,然后再了解编译模式。再来看程序在内存中的分布。 一、CPU ​ CPU是计算机的核心,决定了计算机的数据...

Cchengyoyoy的博客 853

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

C语言程序的内存空间布局

C语言程序是编译后的二进制程序,其对目标操作系统依赖性非常强,如:Linux程序无法在Windows系统上直接运行,反之亦然,再如:64位程序无法允许在32位系统。对于C语言程序的内存存储空间的布局,还是需要了解一下的。 C语言程序主要分为:正文段,初始化数据段,非初始化数据段,栈,堆等。 正文段:CPU执行机器指令的部分,该段是只读的。 初始化数据段:简称数据段,已初始化的变量(全局,静态...

weixin_34206899的博客 204

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

C语言程序的内存布局(一)C语言程序的存储区域

第13章 C语言程序的内存布局 本章介绍C语言程序的内存布局结构,包括连接过程中目标程序各个段的组成和运行过程中各个段加载的情况。 在本章的学习中,读者应重点关注以下内容: C语言程序在内存中各个段的组成 C语言程序连接过程中的特性和常见错误 C语言程序的运行方式 13.1  C语言程序的存储区域 由C语言代码(文本文件)形成可执行程序(二进制文件),需要经过编译-汇编-连接三个阶段

mystudyblog0507的专栏 511

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

15 C语言程序的内存布局

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。提示:以下是本篇文章正文内容,下面案例可供参考​内存是存放运行数据的硬件,硬盘中的程序执行前要先放到内存中才能被CPU去处理,CPU也被设计为多数情况下从内存读取数据和指令,处理的结果也事先存放到内存。内存是与CPU沟通的桥梁。文件是保存在硬盘中的,我们打开一个文件,这个文件从磁盘先加载(复制)到内存。这个过程需要用到一个工具——加载器。

wmjdiidjjisjb的博客 374

C语言程序的内存布局(四)C语言程序的运行

13.4  C语言程序的运行 在嵌入式系统中,程序最终是要放置在内存中运行的,程序的几个段,最终会转化为内存中的几个区域。C语言可执行程序的内存布局如图13-5所示。   (图13-5  C语言可执行程序的内存布局 在内存中,从低地址到高地址,依次是只读段、读写段、未初始化数据段、堆段、栈段。 映像文件中将包含代码段(Code)、只读数据段(RO Data

mystudyblog0507的专栏 935

C语言编程程序的内存如何布局

重点关注以下内容:  C语言程序在内存中各个段的组成  C语言程序连接过程中的特性和常见错误  C语言程序的运行方式  一:C语言程序的存储区域  由C语言代码(文本文件)形成可执行程序(二进制文件),需要经过编译-汇编-连接三个阶段。编译过程把C语言文本文件生成汇编程序,汇编过程把汇编程序形成二进制机器代码,连接过程则将各个源文件生成的二进制机器代码文件组合成一个文件。  C语言编写的程序经过编译-连接后,将形成一个统一文件,它由几个部分组成。在程序运行时又会产生其他几个部分,各个部分代表了不同的存储区域

WWEyang的博客 204
上一篇: 变量的存储
下一篇: “别动我的奶酪!”
utopia123
博客等级 码龄18年 2粉丝 1原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值