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.mzph.cn/pingmian/4313.shtml

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

相关文章

使用C++实现尾插式循环链表结构

在编码中避免不了使用链表,特别是循环链表,很多同学使用时为了省事直接使用C STL库中的链表实现,这样当然很简单也不容易出错,但同时也不可避免的带来了一些问题: 是半个黑盒,虽然能看源码,但是…

【禅道客户案例】同方智慧能源数智化转型新实践 禅道助力前行

同方智慧能源是同方股份有限公司的骨干企业。依托中核集团、清华大学的科技优势,坚持技术和资源双核驱动,基于30多年行业积淀,面向建筑、交通、工业、北方供热、数据中心等主要用能场景提供设计咨询、产品技术、投资建设、运营服务&#xff0…

DELL PowerEdge服务器通过iDRAC升级BIOS遇到的问题

本文对PowerEdge 12G系统,也就是iDRAC 7版本升级BIOS中遇到的几个问题做个总结,对于其他版本理论上应该也是适用的。如果还遇到其他问题,可以添加VX,VX号为 StorageExpert 进行进一步的分析探讨。 第一个问题,成功下载…

Android 11 裁剪系统显示区域(适配异形屏)

概述 在显示技术中,"OverScan"(超扫描)是一种调整显示图像边界的技术。通常情况下,OverScan 会在显示屏的边缘周围裁剪一小部分图像。这种裁剪是为了确保显示内容在屏幕上的完整可见性,尤其是在老式电视或投…

ZABAPGIT问题,导入github上的程序包时报 DBSQL_DUPLICATE_KEY_ERROR

跟踪程序发现在94050行 INSERT seocompotx FROM TABLE it_descriptions 报的错 刚开始,不想着改动他,把seocompotx 表的数据做下指定清楚,但是5次清楚后,果断注释掉 改成 MODIFY seocompotx FROM TABLE it_descriptions。 在用…

航片水体空洞修补

水体空洞情况如下图所示: 水体空洞修补结果如下图所示: 操作视频教程: MCM智拼图软件V8.5-漏洞空洞修补-水体修补_哔哩哔哩_bilibili

鸿蒙OpenHarmony【小型系统 编译】(基于Hi3516开发板)

编译 OpenHarmony支持hb和build.sh两种编译方式。此处介绍hb方式,build.sh脚本编译方式请参考[使用build.sh脚本编译源码]。 使用build.sh脚本编译源码 进入源码根目录,执行如下命令进行版本编译。 ./build.sh --product-name name --ccache 说明&…

基于数据挖掘的斗鱼直播数据可视化分析系统

温馨提示:文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 随着网络直播平台的兴起,斗鱼直播作为其中的佼佼者,吸引了大量用户和观众。为了更好地理解和分析斗鱼直播中的数据,本项目介绍了一个基于数据挖掘的斗鱼直播数据…

【AI导师写作】毕业论文答辩PPT生成

无论是大专、本科或者硕博,撰写毕业论文、开题报告、文献综述、任务书、课程论文、调研报告等都是必不可少的一件事。而这些任务重往往都需要我们花费大量的时间和精力,而“AI导师写作”在这一方面无疑提供了高效和便捷。可毕业季的论文答辩也是每个学者…

C#调用skiasharp实现绘制并拖拽图形

SkiaSharp是基于.net的跨平台二维图形库,封装的谷歌的Skia库,SkiaSharp支持在以下平台或运行时中使用,能够在图片中绘图,也提供控件在Winform、WPF等使用。本文学习skiasharp在Winform的基本用法,并参照参考文献5实现绘…

一键PDF水印添加工具

一键PDF水印添加工具 引言优点1. 精准定位与灵活布局2. 自由旋转与透明度调控3. 精细化页码选择4. 全方位自定义水印内容5. 无缝整合工作流程 功能详解结语工具示意图【工具链接】 引言 PDF作为最常用的文档格式之一,其安全性和版权保护显得尤为重要。今天&#xff…

[移动端] “viewport“ content=“width=device-width, initial-scale=1.0“ 什么意思

布局视口, 代码如下 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>Document</title><style>body,html {margin: 0;padding: 0;}.box {width: 200px;height: 200px;background-color: pi…

数据库基础:理解与应用索引与视图

文章目录 前言 索引视图 前言 数据库管理涉及索引、视图。本基础篇不涵盖索引和视图的高级应用和核心概念。 索引 MySQL索引是提高查询性能的数据结构&#xff0c;类似于书籍目录&#xff0c;帮助数据库快速找到数据行&#xff0c;避免全表扫描。索引可应用于单列或多列&a…

vue 项目关于不同分辨率的电脑网页适配方案

流式布局&#xff1a;这是一种相对灵活的布局方式&#xff0c;页面的元素宽度使用相对宽度&#xff08;例如百分比&#xff09;来定义&#xff0c;而不是使用绝对宽度&#xff08;例如像素&#xff09;。这样&#xff0c;当浏览器窗口大小变化时&#xff0c;元素会自动调整大小…

机器学习理论基础—集成学习(1)

机器学习理论基础—集成学习 个体与集成 集成学习通过构建并结合多个学习器来完成学习任务&#xff0c;有时也称为多分类系统等。 分类&#xff1a; 根据集成学习中的个体学习器的不同可以分为同质集成&#xff08;集成的学习器相同例如全部是决策树&#xff09;&#xff0c…

视频通话实时换脸:支持训练面部模型 | 开源日报 No.235

iperov/DeepFaceLive Stars: 19.7k License: GPL-3.0 DeepFaceLive 是一个用于 PC 实时流媒体或视频通话的人脸换装工具。 可以使用训练好的人脸模型从网络摄像头或视频中交换面部。提供多个公共面部模型&#xff0c;包括 Keanu Reeves、Mr. Bean 等。支持自己训练面部模型以…

字符串类型漏洞之updatexml函数盲注

UPDATEXML 是 MySQL 数据库中的一个函数&#xff0c;它用于对 XML 文档数据进行修改和查询。然而&#xff0c;当它被不当地使用或与恶意输入结合时&#xff0c;它可能成为 SQL 注入攻击的一部分&#xff0c;从而暴露敏感信息或导致其他安全漏洞。 在 SQL 注入攻击中&#xff0…

【数值模型后处理系列】通风系数计算及垂直层插值

一、通风系数 1.1 通风系数简介 通风系数&#xff08;Ventilation Coefficient&#xff0c;VC&#xff09;可以用来表征扩散条件&#xff0c;其计算公式如下&#xff08;参考U S Iyer and P Ernest Raj的文章&#xff09;&#xff1a; 其中mixing depth选用WRF输出的边界层高…

如何我现在是本地的文件路径不是http,用html如何打开

--别给我BB 如何我现在是本地的文件架路径不是http&#xff0c;用html如何打开? 答&#xff1a; 如果你想在HTML中打开本地文件路径的视频&#xff0c;可以使用file://协议。假设你的视频文件在本地的路径为/path/to/your/video.mp4&#xff0c;那么你可以将src属性设置为file…

【Django】初识Django快速上手

Django简介 Django是一个高级的、开源的Python Web框架&#xff0c;旨在快速、高效地开发高质量的Web应用程序 https://developer.mozilla.org/zh-CN/docs/Learn/Server-side/Django/Introduction 安装Django pip install Django如果要知道安装的Django的版本&#xff0c;可…