【C++】内存五大区详解

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
📃个人主页 :阿然成长日记 👈点击可跳转
📆 个人专栏: 🔹数据结构与算法🔹C语言进阶🔹C++
🚩 不能则学,不知则问,耻于问人,决无长进
🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍
文章目录
- 一、C++;内存的五大分区
- 二、栈区和堆区详解
- 1、栈区
- 2、堆区
- 3.⛔️【注意】
- 三、指针的存储位置
- 四、例题巩固
- 五、类的成员函数和静态成员函数
- 一、公共代码区详解
- 2.什么是第二分区?
- 二、函数和函数代码存储位置
前言:
通过文章,我们主要学习在C++\C 中,各个对象,变量,实参等,以及Static修饰的函数或变量的存储位置。 并通过例题来详细讲解。
一、C++;内存的五大分区
- 栈区、 堆区、内存映射段、静态区/数据段、代码段

🔸内核空间:这个区域是系统内部的区域,我们是不可编辑的;
🔸栈区:(主要存储函数运行时而分配的局部变量,函数参数,返回数据,返回地址,指针,const局部变量)
🔸内存映射段:是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信
🔸堆区:由程序员可以自行分配的一块空间。如malloc、new。
🔸 数据段:存储全局变量,静态变量.例如:sattic修饰的静态变量。数据段又分BSS段和DATA段 。
其中BSS存放的是程序员编写的未初始化的全局变量和静态变量(这其中C和C++的BSS还有区别,区别就是:C中的BSS段分为高地址和低地址,高地址是存放全局变量,低地址是存放静态未初始化);
DATA存放已经初始化的全局变量、静态变量和常量。
🔸代码段:又被称为文本段。主要存储程序指令、代码、只读常量。代码段中存放函数(类的成员函数和全局函数)的二进制代码,并且这个区域是只读区域;
二、栈区和堆区详解
1、栈区
栈区向地址减小的方向增长
- 在执行函数时,函数内部变量的存储在栈上。函数执行结束时,系统自动回收。
- 栈区:大小大约只有2MB。分配容量有限
- 执行效率很高:栈内存分配运算内置于处理器的指令集中。
2、堆区
堆区向地址增大的方向增长
- 这个区域是在
运行时使用的,由程序员分配和释放内存,程序结束时操作系统会对其进行回收,(程序员分配内存像malloc、free、new、delete)都是在这个区域进行的; - 产生内存碎片:频繁的new/delete会造成内存空间不连续,产生大量碎片,使程序效率降低。栈不会产生碎片,因为栈是先进后出的队列。
- 空间大:一般来说,对于32位系统下,堆内存空间可以达到4G(2的32次方).从这个角度来看堆的空间是非常大的
- 堆的效率很低:堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。
3.⛔️【注意】
无论堆栈都要防止产生越界,因为越界的结果很严重,要么程序崩溃,要么程序的堆栈结构被破坏,产生意想不到的结果。
三、指针的存储位置
在C++中,指针变量存放在内存的栈区。栈区是一块连续的内存空间,用于存储局部变量和函数调用时的参数。当我们声明一个指针变量时,它会被分配在栈区,并且占用固定大小的内存空间。
指针变量存放在栈区中,而指针所指向的对象或者内存地址则可以位于栈区、堆区或者全局/静态存储区。当我们使用指针来引用一个对象时,指针会保存该对象的内存地址。
需要注意的是,指针变量本身的值(即存放的地址)是存放在栈区的,而指针所指向的对象或者内存地址所对应的数据则可能位于其他不同的内存区域。
四、例题巩固
下面是考察C++内存的一道经典例题。
int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{static int staticVar = 1;int localVar = 1;int num1[10] = { 1, 2, 3, 4 };char char2[] = "abcd";const char* pChar3 = "abcd";int* ptr1 = (int*)malloc(sizeof(int) * 4);int* ptr2 = (int*)calloc(4, sizeof(int));int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);free(ptr1);free(ptr3);
}一、
1. 选择题:选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)globalVar在哪里?____ staticGlobalVar在哪里?____staticVar在哪里?____ localVar在哪里?____num1 在哪里?____char2在哪里?____ *char2在哪里?___pChar3在哪里?____ *pChar3在哪里?____ptr1在哪里?____ *ptr1在哪里?____
解答:

1.globalVar在哪里?____
答:C数据段。globalVar定义在全局,是一个全局变量。
2.staticGlobalVar在哪里?____
答:C.数据段。该变量是static修饰的静态变量,存储于静态区。
3.staticVar在哪里?____
答:C.数据段。该变量虽然处于函数体内,但是它是static修饰的静态变量,仍然存储于静态区。
4.localVar在哪里?____
答:A.栈。该变量是一个普通的成员函数局部变量,存储于栈区。
5.num1 在哪里?____
答:A.栈。该数组是属于普通的函数内的局部变量,依然存储在栈区。
6.🚩char2在哪里?____
答:A.栈。char2是数组名。该数组是属于普通的函数内的局部变量,依然存储在栈区。
7.🚩*char2在哪里?___
答:A.栈。*char2来说,很多同学就会认为它是在【常量区】中,实际上,数组名本身就是一个指针,指向这个字符串的首地址。那我们对首元素地址去进行解引用的话就拿到了首字符的地址,那么这也只是一个字符而已,并不是一个字符串,所以还是存放在【栈区】中的
8.pChar3在哪里?____
答:A.栈。pChar3:是一个指针。指针存储在栈区。
9.*pChar3在哪里?____
答:D.代码段(常量区)。第八题说过pChar3是一个指针,指向一串字符, 该字符存储于常量区,也就是代码段。
10.ptr1在哪里?____
答:A。栈。ptr1仍然是一个指针,存在栈区。
11 . *ptr1在哪里?____
答:B.堆。pttr1指向一块区域 ,对这块区域仅用也就是动态开辟的空间,存储在堆区。
五、类的成员函数和静态成员函数
一、公共代码区详解
之前讲过,类的成员函数并不占用类的内存空间,它们被存储在一个公共代码区。
问题1:公共代码区存储在哪里?
- 公共代码通常存储在特定的分区中,这个分区被称为第二分区。在这个分区中,公共代码是BOOTROM与软件程序共用的。除了公共代码之外,还有其他类型的代码,例如第一程序代码,它被存储在另一个称为第一分区的区域中。当需要运行软件升级时,系统会依据第一分区的起始地址来运行第一分区中的第一程序代码,然后调用第二分区中的公共代码,以接收并校验上位机发送的软件升级文件。如果校验成功,系统将利用软件升级文件来更新第三分区中记录的软件程序使用的除公共代码之外的第二程序代码。
请注意,这里的“分区”可能指的是计算机存储设备(如硬盘或闪存)上的逻辑分区,或者是内存中的不同区域,具体取决于上下文和系统的实现方式。同时,不同的系统或应用程序可能会有不同的分区方案和命名规则,因此具体的分区名称和用途可能会有所不同。
2.什么是第二分区?
在描述公共代码存储于“第二分区”时,这里的“第二分区”通常指的是存储设备(如硬盘、闪存等)上的一个逻辑区域,它被划分出来专门用于存储公共代码。这里的“分区”是相对于整个存储设备而言的,它并不是指分区表中的某一个具体分区(如主分区、逻辑分区等),而是一个更为抽象的概念。
实际上,“第二分区”这个术语可能是特定于某个系统或应用程序的,用于描述存储设备上用于特定目的的一个区域。在不同的上下文或系统中,这个“第二分区”可能有不同的具体含义和用途。
如果您是在讨论某个具体的嵌入式系统、操作系统或应用程序中的分区方案,那么“第二分区”可能是该方案中定义的一个特定区域,用于存储公共代码、库函数、系统文件等共享资源。这个分区可能是由系统的启动加载器(BOOTROM、BIOS等)在启动时加载,并由运行时的程序或操作系统使用。
然而,在没有更多上下文信息的情况下,很难准确地说“第二分区”属于哪个具体的分区类型(如主分区、扩展分区、逻辑分区等),因为这取决于具体的分区方案和实现细节。如果您需要更详细的信息,建议查阅相关的系统文档、开发指南或分区表规范。
二、函数和函数代码存储位置
1.函数代码都存储在代码段(文本段)。
- 无论是静态成员函数还是普通成员函数,它们的函数代码(指令)都存储在程序的代码段(也称为文本段或指令段)中,并在需要时被调用。代码段是只读的,并且包含程序执行时所需的所有指令。
2.静态成员函数和普通成员函数的主要区别在于它们对类成员变量的访问权限和调用方式,而不是它们在内存中的物理存储位置。
- 普通成员函数总是与类的实例(即对象)相关联。它们通常需要一个隐式的
this指针来访问对象的非静态成员。 - 静态成员函数不与任何特定的类实例相关联。它们可以在没有创建类对象的情况下被直接使用
类名去调用,因此不能直接访问类的非静态成员(变量或函数),除非显式地通过对象或指针来访问。 静态成员函数只能直接访问静态成员变量或其他静态成员函数,而普通成员函数可以访问所有类型的成员变量和函数。
相关文章:
【C++】内存五大区详解
💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …...
Django学习笔记教程全解析:初步学习Django模型,初识API,以及Django的后台管理系统(Django全解析,保姆级教程)
把时间用在思考上是最能节省时间的事情。——[美]卡曾斯 导言 写在前面 本文部分内容引用的是Django官方文档,对官方文档进行了解读和理解,对官方文档的部分注释内容进行了翻译,以方便大家的阅读和理解。 概述 在上一篇文章里࿰…...
Python学习之路-爬虫提高:selenium
Python学习之路-爬虫提高:selenium 什么是selenium Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,Selenium 可以直接运行在浏览器上,它支持所有主流的浏览器(包括PhantomJS这些无界面的浏览器)…...
Rust基础拾遗--进阶
Rust基础拾遗 前言1.结构体1.1 具名字段型结构体1.2 元组型结构体1.3 单元型结构体1.4 结构体布局1.5 用impl定义方法1.5.1 以Box、Rc或Arc形式传入self1.5.2 类型关联函数 1.6 关联常量1.7 泛型结构体1.8 带生命周期参数的泛型结构体1.9 带常量参数的泛型结构体1.10 让结构体类…...
数据同步工具对比——SeaTunnel 、DataX、Sqoop、Flume、Flink CDC
在大数据时代,数据的采集、处理和分析变得尤为重要。业界出现了多种工具来帮助开发者和企业高效地处理数据流和数据集。本文将对比五种流行的数据处理工具:SeaTunnel、DataX、Sqoop、Flume和Flink CDC,从它们的设计理念、使用场景、优缺点等方…...
随机过程及应用学习笔记(四) 马尔可夫过程
马尔可夫过程是理论上和实际应用中都十分重要的一类随机过程。 目录 前言 一、马尔可夫过程的概念 二、离散参数马氏链 1 定义 2 齐次马尔可夫链 3 齐次马尔可夫链的性质 三、齐次马尔可夫链状态的分类 四、有限马尔可夫链 五、状态的周期性 六、极限定理 七、生灭过…...
prometheus
文章目录 一、Prometheus简介什么是Prometheus?Prometheus的优势Prometheus的组件、架构Prometheus适用于什么场景Prometheus不适合什么场景 二、相关概念数据模型指标名称和标签样本表示方式 指标类型Counter计数器Gauge仪表盘Histogram直方图Summary摘要 Jobs和In…...
Vi 和 Vim 编辑器
Vi 和 Vim 编辑器 vi 和 vim 的基本介绍 Linux 系统会内置 vi 文本编辑器 Vim 具有程序编辑的能力,可以看做是 Vi 的增强版本,可以主动的以字体颜色辨别语法的正确性,方便程序设计。 代码补完、编译及错误跳转等方便编程的功能特别丰富&…...
算法沉淀——队列+宽度优先搜索(BFS)(leetcode真题剖析)
算法沉淀——队列宽度优先搜索(BFS) 01.N 叉树的层序遍历02.二叉树的锯齿形层序遍历03.二叉树最大宽度04.在每个树行中找最大值 队列 宽度优先搜索算法(Queue BFS)是一种常用于图的遍历的算法,特别适用于求解最短路径…...
编辑器的新选择(基本不用配置)
Cline 不用看网上那些教程Cline几乎不用配置。 点击设置直接选择Chinese, C直接在选择就行了。 Cline是一个很好的编辑器,有很多懒人必备的功能。 Lightly 这是一个根本不用配置的C编辑器。 旁边有目录,而且配色也很好,语言标准可以自己…...
算法沉淀——栈(leetcode真题剖析)
算法沉淀——栈 01.删除字符串中的所有相邻重复项02.比较含退格的字符串03.基本计算器 II04.字符串解码05.验证栈序列 栈(Stack)是一种基于先进后出(Last In, First Out,LIFO)原则的数据结构。栈具有两个主要的操作&am…...
耳机壳UV树脂制作私模定制耳塞需要注意什么问题?
制作私模定制耳塞需要注意以下问题: 耳模制作:获取准确的耳模是制作私模定制耳塞的关键步骤。需要使用合适的材料和方法,确保耳模的准确性和稳定性。材料选择:选择合适的UV树脂和其它相关材料,确保它们的质量和性能符…...
easyx搭建项目-永七大作战(割草游戏)
永七大作战 游戏介绍: 永七大作战 游戏代码链接:永七大作战 提取码:ABCD 不想水文了,直接献出源码,表示我的诚意...
nginx命名location跳转的模块上下文继承
目录 1. 缘起2. 解决方案2.1 保留指定模块的上下文信息2.2 获取指定模块的上下文信息2.3 设置指定模块的上下文信息2.4 设置模块上下文是否需要继承标记2.5 对openrety lua代码的支持 1. 缘起 nginx提供了非常棒的功能,命名location,如文章nginx的locati…...
洛谷 P2678 [NOIP2015 提高组] 跳石头 (Java)
洛谷 P2678 [NOIP2015 提高组] 跳石头 (Java) 传送门:P2678 [NOIP2015 提高组] 跳石头 题目: [NOIP2015 提高组] 跳石头 题目背景 NOIP2015 Day2T1 题目描述 一年一度的“跳石头”比赛又要开始了! 这项比赛将在一条笔直的河道中进行&…...
第2讲投票系统后端架构搭建
创建项目时,随机选择一个,后面会生成配置properties文件 生成文件 maven-3.3.3 设置阿里云镜像 <?xml version"1.0" encoding"UTF-8"?><!-- Licensed to the Apache Software Foundation (ASF) under one or more cont…...
Flask 入门7:使用 Flask-Moment 本地化日期和时间
如果Web应用的用户来自世界各地,那么处理日期和时间可不是一个简单的任务。服务器需要统一时间单位,这和用户所在的地理位置无关,所以一般使用协调世界时(UTC)。不过用户看到 UTC 格式的时间会感到困惑,他们…...
FileZilla Server 1.8.1内网搭建
配置环境服务器服务器下载服务器配置服务器配置 Server - ConfigureServer Listeners - Port 协议设置 Protocols settingsFTP and FTP over TLS(FTPS) Rights management(权利管理)Users(用户) 客户端建立连接 配置环境 服务器处于局域网内: 客户端 < -访问- > 公网 &l…...
C++LNK1207中的 PDB 格式不兼容;请删除并重新生成
在打开别人发的C文件时,可能出现该报错 解决办法 打开资源管理器,找到原来的路径 进入Debug, 找到对应的PDB文件删除即可。...
小白学习Halcon100例:如何利用动态阈值分割图像进行PCB印刷缺陷检测?
文章目录 *读入图片*关闭所有窗口*获取图片尺寸*根据图片尺寸打开一个窗口*在窗口中显示图片* 缺陷检测开始 ...*1.开运算 使用选定的遮罩执行灰度值开运算。*2.闭运算 使用选定的遮罩执行灰度值关闭运算*3.动态阈值分割 使用局部阈值分割图像显示结果*显示原图*设置颜色为红色…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...
【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
Python常用模块:time、os、shutil与flask初探
一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...
