浅析C/C++的内存分段

news2024/11/26 20:37:41

这部分是计算机系统相关的知识,碍于本人才疏学浅,如本文存在疏漏或者错误,还望大佬能帮忙指出,感激不尽。

内存分段

从狭义上讲内存的分段可以分为堆、栈、数据段以及代码段(内存映射区比较复杂,暂不涉及),大致内容可以参考下图:

但其实细说的话其实并没有这么简单。在编译阶段,编译器生成的​目标文件(.o或.obj)中至少包括编译后的机器指令代码、数据,以及链接时所需要的的一些信息(比如符号表、调试信息、字符串等)。其中,目标文件将这些信息按不同的属性以“ 段 ”(segment)的形式存储。如下是一些我们经常会提到的段:

这里我们主要分析表格中常见的段信息,虽然还有其他段,例如注释信息段( .comment )等,但它并不是我们关注的重点。

​下图是一个目标文件的图例分析,主要分析代码和数据分别存放在哪些段中。图中并没有给出堆栈的信息,因为堆栈只有在程序被装载运行时才会分配内存,而在目标文件这个阶段还没有分配栈段的内存。而且堆栈相对来说比较熟悉,所以也就无伤大雅了。

各段说明

原图出处: 实例说明代码段(.text)、数据段(.data)、bss段、只读数据段……

堆和栈我们经常使用,这里就不多说了。堆区就是相当于直接在内存中进行操作,但实际上是在虚拟内存中操作的,并不会直接干扰物理内存。而栈则是程序运行时创建的栈帧。下面我们来介绍剩下数据段和代码段。

代码段:

程序的源代码(包括函数等)编译后的机器指令就会放在代码段,即 .text 段中。在经典的x86体系结构中,代码段通常包含了程序的函数、方法和一些固定的指令集等信息。

数据段:

数据段包括 .data 、 .bss 、 .rodata 三个部分,暂且认为程序中的全局变量和局部变量就是数据段。那么为什么数据段要分成 .data 、 .bss 、 .rodata 三个部分呢?

其主要因素有两个:是否占用内存空间、读写权限如何。

已初始化的全局变量和局部静态变量保存在 .data 段,未初始化的全局变量和局部静态变量一般放在 .bss 段。理论上讲,未初始化的全局变量也是应该放在.data段的,但由于它们都是0,所以为它们在.data段分配空间并且存放数据0也就没有必要了。其中,.bss 段并不会占用磁盘空间,只会在程序加载到内存时分配相应的空间。这种懒加载的特性可以节省可执行文件的大小,特别是当程序中包含大量未初始化的全局或静态变量时。
 .data段和 .bss 段中的都是可读写的数据,而 .rodata 存放的是只读数据,主要是一些const变量、字符串常量等。单独设立 .radata 段的好处是:在程序加载的时候可以将 .rodata 段的属性映射成只读,这样对这个段的任何修改操作都作为非法操作处理。另外在某些平台还可以将 .rodata 段存放在只读存储器,例如ROM,通过硬件保证只读。

那么为什么要把 “代码段” 和 “数据段” 分开存放呢?

当程序被装载后,数据和指令分别被映射到两个虚拟内存区域。数据段对进程来讲是可读写的,而代码段对进程来说是只读的,所以这两个虚拟内存区域的权限可以被分别设置为可读写和只读,防止程序的指令被有意和无意地改写。
现代CPU的缓存一般被设计成数据缓存和指令缓存分离,程序的指令和数据被分开存放对CPU的缓存命中率提高有好处。
当系统中运行着多个该程序的副本时,例如多个线程同时都运行同一个程序,它们的代码段指令都是一样的,所以内存中只需要保存一份该程序的代码段,然后将每个副本进程的数据段区域分来,这样可以节省大量空间。

分段与分区的对应

所以其实之前将可执行程序分为堆区、栈区、静态全局区、文字常量区、代码区这大分区是有迹可循的。代码区对应的是text段。文字常量区对应的就是rodata段。静态全局区就是对应的data段和bss段,因为这两个分段是挨在一起的,所以统称为静态全局区是没毛病的。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++ Concurrency in Action 2nd Edition

《C Concurrency in Action - SECOND EDITION》的中文翻译-面圈网 (mianshigee.com) C/C 学习教程源码-C/C源码推荐-面试哥 (mianshigee.com) 作者正是为C11标准引入线程库的C标准委员会成员本人!并且本书作者还编写了众多构成C标准的多线程和并发相关的提案、制定…

基于天鹰算法的无人机航迹规划-附代码

基于天鹰算法的无人机航迹规划 文章目录 基于天鹰算法的无人机航迹规划1.天鹰搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要:本文主要介绍利用天鹰算法来优化无人机航迹规划。 1.天鹰搜索算法 …

如何使用腾讯云+Picgo搭建图床

目录 一、进入腾讯云进行实名认证 二、领取免费存储额度 2.1新用户界面概览就可以领取 三、开始创建远端图床并生成秘钥等信息 3.1创建存储桶 3.2配置基本信息 3.3配置高级选项 3.4确认配置页面点击创建即可 3.5创建访问秘钥 3.6查看秘钥等信息 3.7查看桶名称 四、图…

《向量数据库指南》——开源框架NVIDIA Merlin 向量数据库Milvus

NVIDIA Merlin & Milvus 推荐系统 pipeline 中至关重要的一环便是为用户检索并找到最相关的商品。为了实现这一目标,通常会使用低维向量(embedding)表示商品,使用数据库存储及索引数据,最终对数据库中数据进行近似最近邻(ANN)搜索。这些向量表示是通过深度学习模型获…

Sentinel黑白名单授权规则解读

目录 基本介绍 代码实战 架构说明 RequestOriginParser的实现类 网关添加请求头 配置授权规则 基本介绍 授权规则可以对请求方来源做判断和控制。 很多时候,我们需要根据调用来源来判断该次请求是否允许放行,这时候可以使用 Sentinel 的来源…

zigbee路灯无线通讯机制

zigbee路灯无线通讯机制 wang20160630 前言 目前路灯上通讯主要有电力载波和无线通讯;各有利弊,众说纷纭;本文不对两种技术进行比较,也不讨论哪种好,毕竟同种通讯模块,有的开发出来稳定,有的…

cesium示例教程100+目录

cesium示例教程100旨在为开发者提供简单快捷的代码示例,复制即可用。在每一个示例中,解释相应的API知识点,做到简易实现,轻松学会。 文章目录 目录基础设置及界面配置设置材质material显示图形绘制图形加载文件数据加载各种地图综…

2023.11.6-分析 Gateway 和 VirtualService

2023.11.6-分析 Gateway 和 VirtualService 目录 本节实战 实战名称 正文 前面我们创建了一个 Gateway 和 VirtualService 对象,用来对外暴露应用,然后我们就可以通过 ingressgateway 来访问 Bookinfo 应用了。那么这两个资源对象是如何实现的呢&…

PyTorch深度学习实战——图像着色

PyTorch深度学习实战——图像着色 0. 前言1. 模型与数据集分析1.1 数据集介绍1.2 模型策略 2. 实现图像着色相关链接 0. 前言 图像着色指的是将黑白或灰度图像转换为彩色图像的过程,传统的图像处理技术通常基于直方图匹配和颜色传递的方法或基于用户交互的方法等完…

提升你的C#技能:掌握PrintDocument实现打印操作的秘诀

前言: 我们用C#在开发应用的时候,经常需要打印操作,比如你需要打印某些记录,或者是某些图像都需要用到打印的操作,比如我需要打印报警记录,按照指定的格式打印出来,我需要PrintDocument类&…

项目管理之如何识别并应对项目风险

项目风险管理是项目管理中不可忽视的环节,如何识别并应对项目的风险对于项目的成功实施至关重要。本文将介绍风险管理的流程、风险分解结构、定性及定量风险评估方法,以及消极和积极的风险应对策略,旨在帮助读者更好地理解和应对项目风险。 …

(1)(1.12) LeddarTech LeddarVu8

文章目录 前言 1 连接到自动驾驶仪 2 参数说明 前言 LeddarTech LeddarVu8 是一款长距离(185m)激光雷达,可在 16 度至 99 度视场范围内提供 8 个单独的距离,具体取决于所使用的型号。ArduPilot 始终使用所提供的 8 个距离中最…

VSCode设置中文语言界面(VScode设置其他语言界面)

一、下载中文插件 二、修改配置 1、使用快捷键 CtrlShiftP 显示出搜索框 2、然后输入 configure display language 3、点击 (中文简体) 需要修改的语言配置 三、重启 四、可能出现的问题 1、如果configure display language已经是中文配置,界面仍是英文 解决&a…

优化C++资源利用:探索高效内存管理技巧

W...Y的主页 😊 代码仓库分享💕 🍔前言: 我们之前在C语言中学习过动态内存开辟,使用malloc、calloc与realloc进行开辟,使用free进行堆上内存的释放。进入C后对于动态内存开辟我们又有了新的内容new与dele…

【C++】一篇文章搞懂auto关键字及其相关用法!

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …

C语言基础篇1:数据类型、常量、变量

1 C语言基础 1.1 关键字 在C语言中,关键字是指被赋予特定意义的一些单词,不能把这些单词作为标识符来使用.C语言一共有32个关键字,如下图。在后面的学习中会逐渐接触到这些关键字的具体使用用法。 1.2 标识符 标识符可以简单的理解为一个名字…

第四届辽宁省大学生程序设计竞赛(正式赛)(12/13)

AC情况 赛中通过赛后通过暂未通过A√B√C√D○E○F√G√H√I○J√K—L√M√ 整体体验 easy:ABFHL mid:MJGC hard:IDKE 心得 感觉出了一堆典题,少数题还有些意思,E题确实神仙 题解 A. 欢迎来到辽宁省赛&#x…

bff层解决了什么痛点

bff层 -- 服务于前端的后端 什么是bff? Backend For Frontend(服务于前端的后端),也就是服务器设计API的时候会考虑前端的使用,并在服务端直接进行业务逻辑的处理,又称为用户体验适配器。BFF只是一种逻辑…

基于爬行动物算法的无人机航迹规划-附代码

基于爬行动物算法的无人机航迹规划 文章目录 基于爬行动物算法的无人机航迹规划1.爬行动物搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要:本文主要介绍利用爬行动物算法来优化无人机航迹规划。 …

Python|OpenCV-图像的添加和混合操作(8)

前言 本文是该专栏的第8篇,后面将持续分享OpenCV计算机视觉的干货知识,记得关注。 在使用OpenCV库对图像操作的时候,有时需要对图像进行运算操作,类似于加法,减法,位操作等处理。而本文,笔者将针对OpenCV对图像的添加,混合以及位操作进行详细的介绍说明和使用。 下面,…