C++高级特性:C/C++内存结构模型(十一)

1、内存结构
  • C/C++语言一只被认为是一种底层语言,与其他语言不一样,对内存结构理解是C/C++程序员从入门到入土的开端。

  • 其他编程语言对内存管理是透明的,程序员无序关心可以认为是一个黑盒;而C/C++不一样理解好内存结构有利于编写健壮性的代码

  • C++的内存结构主要涉及以下区域

    • 代码区:存储程序的机器码指令,包括执行程序和只读数据:全局常量、const修饰的变量、字符串常量
    • 全局/静态存储区:存储全局变量和静态变量,其生命周期贯穿整个程序执行过程的变量!
    • 堆区:用于动态分配内存,存储在堆上的数据的生命周期由程序员自行管理(地址由低到高)
    • 内存映射区:mmap共享映射区,主要包括动态库.dll/.so、文件映射、匿名映射
    • 栈区:用于存储函数调用信息、局部变量、临时数据等,遵循后进先出的原则(地址由高到低)
      在这里插入图片描述
2、内存各区介绍
  1. 代码段可制度数据段通常在程序加载时有操作系统加载到内存,一旦加载就不能被修改
  2. 在函数调用时,函数的机器码也存储在代码段中,每个函数有其独特的代码段地址
  3. 字符串常量等只读数据段中的数据是不可修改的,任何企图修改这些数据的尝试都会导致运行时错误
2.1、代码区
  • 在C++程序中,代码区是存储程序执行代码的一部分内存区域。它通常被划分为两个主要部分:代码段(.text)和只读数据段(.rodata)
  • 这里说的代码区是指已经运行并且加载到内存中的可执行的二进制指令,并不是存储在磁盘上的源代码文件
2.1.1、代码段(.text)
  • 结构:代码段存储程序的可执行指令,即机器码。这是程序中实习执行的代码部分。
  • 使用场景:包括程序的函数、方法、控制流等。这部分内存是只读的,程序在运行时不能修改代码段的内容
2.1.2、只读数据段(.rodata)
  • 只读数据段:rodata是read-only data的缩写
  • 结构:只读数据段存储常量数据,例如字符串常量,以及全局或静态变量的初始化值。
  • 使用场景:用于存储不可修改的数据。字符串字面量是一个常见的只读数据段的例子
2.1、小结

代码区有两个很重要的特性:

  • 只读(read only):代码区的东西都是只读的,这意味着程序在运行时这部分的内容不被修改,有助于保证程序执行区间的数据的一致性和安全性
  • 可复用性(Sharable):代码区的内容通常是共享的,有趋势对于相同的程序的多个实例或同时运行起来的多个程序来说,多个程序实例可以共享相同的机器码,有助于节省内存

这些特点使得代码区能够更有效地支持多个程序的并发执行,并在运行时提供一定程序的保护,确保代码和只读数据的完整性。

2.2、全局/静态存储区

全局/静态存储区是程序中用于存储全局变量和静态变量的内存区域。这些变量在程序的整个声明周期内存在,并且其内存分配发生在程序启动时,知道程序结束。全局/静态存储区包括两个主要部分:全局变量区和静态变量区。

  • .data段
    • 已初始化的全局变量、静态变量存放在.data段。
    • .data段占用可执行文件空间,其内容有程序初始化。
  • .bss段
    • 未初始化的全局变量、静态变量存放在.bss段。
    • 初始化为0的全局变量、静态变量存放在.bss段。
    • .bss段不占用可执行文件空间,其内容由操作系统初始化。
  • 注意事项:
    • 全局、静态存储区的数据在程序启动时分配,在程序结束时释放
    • 全局变量区的数据可以被整个程序访问,而静态变量区的数据访问权限与其定义的位置有关。
    • 多线程访问,全局变量和静态变量可能需要额外的同步/互斥机制,以确保多个线程对它们的安全访问。
2.3、堆区
  • 堆区是程序运行时用于动态分配内存的一种内存区域,也称为自由存储区。
  • 堆上的内存可以在运行时动态分配和释放,由程序员自行负责管理其生命周期
  • 使用场景
    • 堆是有操作系统分配的一块较大的内存区域,可以分配出较大的一块虚拟内存连续的地址
    • 动态内存分配:当程序无法确定需要多少内存时或者需要在程序的不同部分共享数据时,使用堆上的内存非常有用
    • 对象的动态创建和销毁:使用new 和 malloc操作符分配的内存,使用delete和free操作释放相应的内存。
2.4、栈区
  • 使用场景:
    • 存储函数的局部变量:酶促函数调用时,其局部变量被分配到栈上,函数返回时将这些变量自动释放
    • 存储函数的调用信息:每次函数调用时,函数的地址和一些其他信息被压入栈中,函数返回时再从栈中弹出这些信息
  • 栈帧:
    • 在函数调用时,一个栈帧(Stack Frame)被压入栈中。
    • 栈帧包含了函数的局部变量、返回值地址和其他与函数调用相关的信息。
    • 栈帧主要是通过寄存器地址偏移来实现的。
  • 栈的管理通常有编译器负责。编译器根据程序的结构和函数调用关系来分配和管理栈空间。在编译阶段,编译器会生成一些代码来处理栈的操作,包括栈帧的创建和销毁,局部变量的分配和释放,以及函数调用时的相关操作
    • 分析函数调用关系:编译器需要了解程序中函数的调用关系,以便正确生成栈帧和处理函数调用时的参数传递和返回值
    • 分配栈空间:对于每个函数,编译器需要决定分配多少空间用于栈帧,以容纳局部变量、函数操作、返回地址等
    • 生成栈操作指令:编译器会生成相同的汇编或机器码指令,用于执行栈的压栈和出栈操作,以及处理函数调用时的栈操作

高级语言中一般不需要管理栈帧的操作,在低级(汇编)语言中,程序员有更多的控制权,可以直接操作栈,高级语言中这种底层的栈帧操作通常有编译器自动处理。

2.5、内存映射区
  • 这个区域很灵活主要负责:
    • 动态库:windows下的.dll库、Linux下的.so库的加载与库调用
    • 共享内存映射、文件映射的处理
    • malloc分配超过128k也会进入内存映射区进行分配空间
    • 其分配方向不同:32位和64位分配的方向相反
2.6、内核空间
  • 所有程序共享的一个空间

  • 用户代码不能读写的一段地址

3、总结
  • 作为一个专业的C++使用者来说,清楚的知道自己的代码变量存储的区域会有非常大的好处,补单能够写出高性能代码,而且有助于减少一些深层次的BUG。

  • 使用C++内存的一些注意事项

    • 内存泄漏:确保在动态分配内存后找个合适的时机释放掉,避免出现内存泄漏

    • 野指针:注意在指针使用后及时置为nullptr,避免访问已经释放的内存

    • 栈溢出:谨慎使用递归或者在栈区使用巨大的空间分配局部变量,以免造成栈溢出

    • 悬挂指针:避免悬挂指针的问题,即指向已经释放的内存区域

    • 智能指针:考虑使用C++的智能指针(std::unique_ptr、std::shared_ptr),提高内存管理的安全性和便利性。

    • 局部变量生命周期:理解局部变量的生命周期,确保在离开其作用域前不在访问。

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

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

相关文章

碎碎念,最近做了几款小产品...

极简番茄时钟 一款 Mac 版「极简番茄时钟」软件。 知识卡片制作工具 主打简单,同时支持 Markdown 语法。 智能微信助手 让管理变得轻松,沟通更加高效。 感兴趣,欢迎来这里一起交流,限时免费 ~

【软件安装】(十六)双系统Ubuntu22.04引导启动菜单的默认项

一个愿意伫立在巨人肩膀上的农民...... 好学的人总是喜欢在电脑上安装双系统,可是安装好系统之后,就会出现默认启动优先级的苦恼,如果在Bios中设置Windows引导启动为优先启动,那么每次想要进如Ubuntu系统就都需要重新设置Bios。如…

基于 Redis 发布订阅实现服务注册与发现

写在前面 其实很少有公司会使用 Redis 来实现服务注册与发现,通常是ETCD、NACOS、ZOOKEEPER等等,但是也不妨碍我们了解。本文会先介绍 Redis 的发布/订阅模式,接着基于这个模式实现服务注册与发现。 Redis发布订阅流程图: Red…

北京半导体展会2024时间(入场时间+闭馆时间)

2024年第二十一届中国国际半导体博览会(IC CHINA) 时 间:2024 年 9 月 5 一 7 日 地 点:中国北京 北人亦创国际会展中心 作为中国半导体行业协会主办的唯一展览会,自 2003 年起已连续成功举办二十届,是…

ZCT-80零序电流互感器配继电器组合用,电流200/1.5mA JOSEF约瑟

ZCT-80零序电流互感器配继电器组合用,电流200/1.5mA ■ 互感器用于接地保护的装置 ■ 检测零序电流的互感器 ■ 适用于EOCR继电器 功能特点: 专用于剩余电流的检测。 与ELR继电器配合使用。 产品外壳采用ABS阻燃材料,抗干扰能力强,测量…

RFC 6071: IP Security (IPsec) and Internet Key Exchange (IKE) Document Roadmap

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/96882d1fb67b4383bc77c4dd421f7b

Ubuntu中的 Everything 搜索软件 ==> fsearch

本文所使用的 Ubuntu 系统版本是 Ubuntu 22.04 ! 在 Windows 中,我经常使用 Everything 来进行文件搜索,搜索效率比 Windows 自带的高出千百倍。 那么在 Ubuntu 系统中,有没有类似的软件呢?那必须有,它就是 FSearch 。…

【单调栈】3113. 边界元素是最大值的子数组数目

本文涉及的基础知识点 单调栈分类、封装和总结 LeetCode 3113. 边界元素是最大值的子数组数目 给你一个 正 整数数组 nums 。 请你求出 nums 中有多少个子数组,满足子数组中 第一个 和 最后一个 元素都是这个子数组中的 最大 值。 示例 1: 输入&#…

区块链 | OpenSea:Wyvern protocol

目录 Wyvern on the OpenSea 1 交易流程 1.1 卖家 1.2 买家 2 组成部分 2.1 WyvernProxyRegistry 2.2 OwnableDelegateProxy 2.3 NFT Contract 2.4 OpenSea Order Book 2.5 Wyvern Exchange Contract 3 总结 🥑原文:Wyvern on the …

交通气象站监测站

TH-GQX8交通运输在人们的日常生活中扮演着越来越重要的角色。然而,气候变化、环境污染等因素对交通安全产生了极大的影响。为了应对这些挑战,交通气象站监测站应运而生,成为守护交通安全的重要利器。 一、交通气象站监测站的功能 交通气象站…

路透社:美国SEC将拒绝以太坊ETF

4月25日,据路透社报道,美国SEC在下个月将拒绝以太坊现货ETF申请。根据4位知情人士表示,在最近几周与美国证券交易委员会(SEC)进行了会议之后,美国发行商和其他公司预计SEC将拒绝他们推出与以太坊价格挂钩的…

OpenMesh 网格高斯曲率计算(二)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 Mesh曲率特征通常指的是在三维几何网格(Mesh)上计算的曲率相关的一系列特征,包括主曲率、高斯曲率、平均曲率等。这些曲率特征提供了对Mesh表面形状的详细描述,对于表面形状分析、形状比较和几何建模等领域非常…

《C++的类型转换》

目录 一、c语言中的类型转换 1、隐式类型转化: 2、强制类型转化: 3、缺点 二、c新的类型转换 1、内置类型转为自定义类型 3、自定义类型转换为内置类型 三、C的规范的强制类型转换 1、C新增四种规范的类型转换的原因 2、static_cast 3、reint…

头歌实践教学平台:CG5-v1.0-简单光照效果

第2关:OpenGL球体镜面反射 一.任务描述 根据提示,在右侧修改代码,并自己绘制出图形。平台会对你编写的代码进行测试。 1.本关任务 为在场景中增加光照,需要执行以下步骤。 (1).设置一个或多个光源,设定它的有关属性…

信息系统项目管理师0074:数据集成(5信息系统工程—5.3系统集成—5.3.3数据集成)

点击查看专栏目录 文章目录 5.3.3数据集成1.数据集成层次2.异构数据集成5.3.3数据集成 数据集成的目的是运用一定的技术手段将系统中的数据按一定的规则组织成为一个整体,使得用户能有效地对数据进行操作。数据集成处理的主要对象是系统中各种异构数据库中的数据。数据仓库技术…

eclipse导入工程提示Project has no explicit encoding set

eclipse导入工程提示Project has no explicit encoding set 文章目录 eclipse导入工程提示Project has no explicit encoding set一、Eclipse的工程导入二、可能的问题1.在工程名下有黄色叹号 一、Eclipse的工程导入 用Eclipse的导入可以将原有工程导入到新环境中 具体方法是&…

1. 房屋租赁管理系统(基于springboot/vue的Java项目)

1.此系统的受众 1.1 在校学习的学生,可用于日常学习使用或是毕业设计使用 1.2 毕业一到两年的开发人员,用于锻炼自己的独立功能模块设计能力,增强代码编写能力。 1.3 亦可以部署为商化项目使用。 2. 技术栈 jdk8springbootvue2mysq5.7&8…

区块链与Web3.0:区块链项目的推广

数字信息时代,一场革命正在酝酿中,那就是区块链与Web3.0的结合。这种结合将会改变我们对于信息传输、存储和使用的方式,并有可能推动媒体行业向新的高度发展。这种转变不仅关系到我们如何获取和使用信息,也涉及到如何用创新的方式…

四、OSPF域间路由

注:区域(area)是以接口进行划分的 描述: R1的g0/0/1接口属于area 0 √ R1属于区域0和区域1 1.设计原则 1、OSPF区域的设计原则: 骨干区域有且只能存在一个 非骨干区域必须和骨干区域相连 多区域时&#…

VulnHub靶机 DC-9 靶机 详细渗透过程

VulnHub靶机 DC-9 打靶实战 详细渗透过程 目录 VulnHub靶机 DC-9 打靶实战 详细渗透过程一、将靶机配置导入到虚拟机当中二、渗透测试主机发现端口扫描Web渗透SQL注入登入后台文件包含SSH爆破提权 一、将靶机配置导入到虚拟机当中 靶机地址: https://www.vulnhub.…
最新文章