【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指针来访问对象的非静态成员。
  • 静态成员函数不与任何特定的类实例相关联。它们可以在没有创建类对象的情况下被直接使用类名去调用,因此不能直接访问类的非静态成员(变量或函数),除非显式地通过对象或指针来访问。
  • 静态成员函数只能直接访问静态成员变量或其他静态成员函数,而普通成员函数可以访问所有类型的成员变量和函数。

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

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

相关文章

片上网络NoC(5)——非直连拓扑

目录 一、前言 二、概念阐述 三、交叉开关 四、蝶形网络 五、clos网络 六、fat tree网络 6.1 clos网络的折叠过程 七、总结 一、前言 本文继续介绍片上网络的拓扑,在之前的文章中,我们已经介绍了片上网络的拓扑指标和直连拓扑的相关内容&#xf…

2、6作业

TCP和UDP的区别 TCP和UDP都是通信协议 TCP提供有连接的,稳定的,无误码无失真无乱序无丢失的通信 UDP提供无连接的,尽力的,可能误码可能乱序,可能丢失的通信 TCP每发一个数据包就需要对方回应一个应答包&#xff0c…

分享88个CSS3特效,总有一款适合您

分享88个CSS3特效,总有一款适合您 88个CSS3特效下载链接:https://pan.baidu.com/s/1pDAyFESnO8HSnCZj4-DOzQ?pwd8888 提取码:8888 Python采集代码下载链接:采集代码.zip - 蓝奏云 学习知识费力气,收集整理更不…

python中库的安装和卸载

1 安装库的基本方法 pip install 库名 2 批量下载(pa.txt放入库的名称和版本要求)格式如图所示: pip install -r pa.txt 3 官网下载安装库 https://pypi.org/project/ 搜索后点击Download files python -m pip install C:\Users\ZHUHUA\Downloads\…

第二节:轻松玩转书生·浦语大模型趣味Demo

参考教程:https://github.com/InternLM/tutorial/blob/main/helloworld/hello_world.md InternLM-Chat-7B 智能对话 Demo 终端运行 web demo 运行 1.首先启动服务: cd /root/code/InternLM streamlit run web_demo.py --server.address 127.0.0.1 --…

如何把华为手机上的数据转移到荣耀手机上?

方法/步骤 点击并进入华为手机(旧手机)的【手机克隆】应用,选择【这是旧设备】; 点击并进入荣耀手机(新手机)的【换机克隆】应用,选择【这是新设备】; 荣耀手机(新…

AtCoder Beginner Contest 340 C - Divide and Divide【打表推公式】

原题链接:https://atcoder.jp/contests/abc340/tasks/abc340_c Time Limit: 2 sec / Memory Limit: 1024 MB Score: 300 points 问题陈述 黑板上写着一个整数 N。 高桥将重复下面的一系列操作,直到所有不小于2的整数都从黑板上移除: 选择…

H12-821_31

31.下面是一台路由器的部分配置,关于该配置描述正确的是: A.源地址为1.1.1.1的数据包匹配第一条ACL语句rule 0,匹配规则为允许 B.源地址为1.1.1.3的数据包匹配第三条ACL语句rule 2,匹配规则为拒绝 C.源地址为1.1.1.4的数据包匹配第四条ACL语句rule 3,匹配规则为允许 D.源地址为…

InstantBox:开箱即用的临时 Linux 环境

在云计算和虚拟化技术日益成熟的今天,我们有时需要一个快速、简单、临时的 Linux 环境来进行各种任务。这就是 InstantBox 的用武之地。 什么是 InstantBox? InstantBox 是一个开源项目,它可以快速启动临时的 Linux 系统,并提供…

自动生成测试用例_接口测试用例自动生成工具

前言 写用例之前,我们应该熟悉API的详细信息。建议使用抓包工具Charles或AnyProxy进行抓包。 har2case 我们先来了解一下另一个项目har2case 他的工作原理就是将当前主流的抓包工具和浏览器都支持将抓取得到的数据包导出为标准通用的 HAR 格式(HTTP A…

Node.js开发-HTTP协议

HTTP协议 1) 概念2) 请求报文的组成3) HTTP 的请求行4) HTTP 请求头5) HTTP 的请求体6) 响应报文的组成7) 创建 HTTP 服务8) 获取 HTTP请求报文9) 设置 HTTP 响应报文10) 设置资源类型(mime类型)11) GET和POST请求的区别 1) 概念 HTTP(hyper…

国产手机大量采用国产OLED屏幕,三星屏占比大幅减少了

在以往采用三星OLED屏幕曾是国产期间手机的标配,然而2023年国产手机品牌突然大幅减少了对三星OLED屏幕的采用,而大幅增加了国产OLED屏幕的采用比例,推动国产OLED屏幕的市占率大幅上涨。 2023年由于高通提前发布销量8G3,由此导致中…