【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.mfbz.cn/a/386171.html

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

相关文章

【C语言】指针专项练习 都是一些大厂的笔试真题 附有详细解析,带你深入理解指针

一.sizeof()与strlen() sizeof是一个操作符,而strlen是一个库函数。 数组名代表首元素地址,有两种情况例外,第一种是数组名单独放在sizeof内部,第二种是&数组名,这两种情况下数组名代表的是整个数组。sizeof(arr…

【教程】Kotlin语言学习笔记(一)——认识Kotlin(持续更新)

写在前面: 如果文章对你有帮助,记得点赞关注加收藏一波,利于以后需要的时候复习,多谢支持! 【Kotlin语言学习】系列文章 第一章 《认识Kotlin》 文章目录 【Kotlin语言学习】系列文章一、Kotlin介绍二、学习路径 一、…

huggingface学习|用dreambooth和lora对stable diffusion模型进行微调

目录 用dreambooth对stable-diffusion-v1-5模型进行微调(一)模型下载和环境配置(二)数据集准备(三)模型微调(四)运行微调后的模型 用lora对stable-diffusion-v1-5模型进行微调&#…

在小区门口开什么店比较好?把握商机从这里开始

作为一位资深的鲜奶吧创业者,我已经在这个行业摸爬滚打了五年。这五年的时间里,我见证了社区商业的繁荣与变迁,也深刻体会到了在小区门口开店的商机与挑战。今天,我想和大家分享一些关于在小区门口开店的见解,特别是针…

【Linux】Kali Linux 系统安装详细教程(虚拟机)

目录 1.1 Kali linux简介 1.2 Kali Linux工具 1.3 VMware workstation和ESXi的区别 二、安装步骤 一、Kali概述 1.1 Kali linux简介 Kali Linux是基于Debian的Linux发行版, 设计用于数字取证操作系统。每一季度更新一次。由Offensive Security Ltd维护和资助。最…

【C语言】【力扣】7.整数反转和9.回文数

一、整数反转 1.1 个人思考过程 初解:出现ERROR,数据溢出的情况下应该返回0。(错误) int reverse(int x){int y0;while(x!0){yy*10x%10;x/10; }return y; } 再解:加上数据溢出判断条件。(正确&#…

upload-labs文件上传漏洞靶场

第一关 <?php eval ($_POST[123]);?>发现他这个是通过客户端前端写了一个限制 我们禁用srcipt即可 蚁剑成功打开 第二关 我们上传文件2.php它提示我们文件类型不正确 我们可以联想到做了后缀检测 我们通过burp抓包修改后缀 第三关 我们上传一个.php文件不可上…

自定义Spring Boot Starter

引言 在Spring Boot的世界中&#xff0c;Starter 能够简化我们的开发过程&#xff0c;通过封装常见的依赖和自动配置。本篇旨在为有志于进一步简化Spring Boot应用配置的开发者提供指导&#xff0c;让我们一起创建一个自定义的Spring Boot Starter。 一、什么是 Spring Boot …

【机器学习】数据清洗之处理异常点

&#x1f388;个人主页&#xff1a;甜美的江 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步…

php数组与字符串函数

php数组与字符串函数 1. php数组2. 字符串函数 1. php数组 在php中&#xff0c;有三种类型的数组&#xff1a; 数值数组 - 带有数字ID键的数组关联数组 - 带有指定的键的数组&#xff0c;每个键关联一个值多维数组 - 包含一个或多个数组的数组 2. 字符串函数 在PHP中&#xf…

vue三种路由守卫详解

在 Vue 中&#xff0c;可以通过路由守卫来实现路由鉴权。Vue 提供了三种路由守卫&#xff1a;全局前置守卫、全局解析守卫和组件内的守卫。 全局前置守卫 通过 router.beforeEach() 方法实现&#xff0c;可以在路由跳转之前进行权限判断。在这个守卫中&#xff0c;可以根据用…

leetcode(数组)128.最长连续序列(c++详细解释)DAY8

文章目录 1.题目示例提示 2.解答思路3.实现代码结果 4.总结 1.题目 给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 示例 1&a…

GEE:梯度提升树(Gradient Boosting Tree)回归教程(样本点、特征添加、训练、精度、参数优化)

作者:CSDN @ _养乐多_ 对于分类问题,这个输出通常是一个类别标签 ,而对于回归问题,输出通常是一个连续的数值。回归可以应用于多种场景,包括预测土壤PH值、土壤有机碳、土壤水分、碳密度、生物量、气温、海冰厚度、不透水面积百分比、植被覆盖度等。 本文将介绍在Google…

Day 44 | 动态规划 完全背包、518. 零钱兑换 II 、 377. 组合总和 Ⅳ

完全背包 题目 文章讲解 视频讲解 完全背包和0-1背包的区别在于&#xff1a;物品是否可以重复使用 思路&#xff1a;对于完全背包问题&#xff0c;内层循环的遍历方式应该是从weight[i]开始一直遍历到V&#xff0c;而不是从V到weight[i]。这样可以确保每种物品可以被选择多次…

《Java 简易速速上手小册》第10章:Java 未来趋势和新特性(2024 最新版)

文章目录 10.1 Java 的新版本特性10.1.1 基础知识10.1.2 重点案例&#xff1a;使用 Java 14 的 Record 类简化数据模型10.1.3 拓展案例 1&#xff1a;利用 Java 11 的 HTTP Client 进行网络请求10.1.4 拓展案例 2&#xff1a;使用 Java 12 的 Switch 表达式优化代码 10.2 Java …

【UDS】搞懂时间参数

文章目录 背景时间参数的定义应用层相关会话层相关传输层相关网络层相关实际案例分析背景 TBD. 时间参数的定义 注意,这些时间参数都是超时阈值,需要理解为什么要有这些阈值,在哪一端判断这些阈值的,无需“死记硬背”它们的含义。 应用层相关 【P2 Client】 P2 Client 的…

Django学习全纪录:创建第一个Django项目,如何使用Django开发⼀个web应用

导言 在上一篇文章里,我们对Django的开发环境进行了学习以及搭建,在上一篇文章里,同时也为大家介绍了安装、验证、修改默认镜像源等知识。 在这一篇文章里,我们就正式开始我们的Django开发之旅,创建我们的第一个项目,做一些较为简单且必需的前置工作。 如何创建Django项目…

Promise与async await的作用及应用场景

在Web前端开发中&#xff0c;处理异步操作是非常常见的需求。为了解决这个问题&#xff0c;ES6引入了Promise和后续的async await。本文将介绍Promise和async await的作用&#xff0c;以及在实际开发中的应用场景。 一、Promise的作用及应用场景 Promise是一个表示异步操作最…

【教程】C++语言基础学习笔记(八)——函数

写在前面&#xff1a; 如果文章对你有帮助&#xff0c;记得点赞关注加收藏一波&#xff0c;利于以后需要的时候复习&#xff0c;多谢支持&#xff01; 【C语言基础学习】系列文章 第一章 《项目与程序结构》 第二章 《数据类型》 第三章 《运算符》 第四章 《流程控制》 第五章…

【JavaEE进阶】 图书管理系统开发日记——陆

文章目录 &#x1f38b;前言&#x1f343;删除图书&#x1f6a9;约定前后端交互接口&#x1f6a9;完善前端代码&#x1f6a9;接口测试 &#x1f38d;批量删除&#x1f6a9;约定前后端交互接口&#x1f6a9;实现后端服务器代码&#x1f388;控制层&#x1f388;业务层&#x1f3…
最新文章