【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.rhkb.cn/news/257446.html

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

相关文章

Flutter学习(八)Flutter_Boost接入

背景 基于安卓的原生项目,进行Flutter的接入,进行混合开发。 参考链接 官方地址:link fullter_boost配置:link git代理配置:link kotlin语法集成:link 混合开发的坑:link 开发环境 as4…

【从Python基础到深度学习】7. 使用scp命令实现主机间通讯

一、生成 SSH 密钥对 ssh-keygen 是一个用于生成 SSH 密钥对的命令行工具,用于身份验证和加密通信 ssh-keygen 二、将本地主机上的 SSH 公钥添加到远程主机 ssh-copy-id 命令用于将本地主机上的 SSH 公钥添加到远程主机上的 authorized_keys 文件中,…

第12讲创建图文投票实现

创建图文投票实现 图文投票和文字投票基本一样&#xff0c;就是在投票选项里面&#xff0c;多了一个选项图片&#xff1b; <view class"option_item" v-for"(item,index) in options" :key"item.id"><view class"option_input&qu…

【漏洞复现】狮子鱼CMS某SQL注入漏洞

Nx01 产品简介 狮子鱼CMS&#xff08;Content Management System&#xff09;是一种网站管理系统&#xff0c;它旨在帮助用户更轻松地创建和管理网站。该系统拥有用户友好的界面和丰富的功能&#xff0c;包括页面管理、博客、新闻、产品展示等。通过简单直观的管理界面&#xf…

golang集成sentry: go-redis

网上没有找到go-redis集成sentry的库&#xff0c; 所以我简单实现了一个 代码&#xff1a; https://github.com/Shujie-Tan/go-redis-sentry 使用方法&#xff1a; import (redis_sentry "github.com/Shujie-Tan/go-redis-sentry" ) rdb : redis.NewClient(&re…

【C语言】模拟实现库函数qsort

qsort的头文件是stdlib.h 他的四个参数分别是要进行排序的数组base的首地址&#xff0c;base数组的元素个数&#xff0c;每个元素的大小&#xff0c;以及一个函数指针&#xff0c;这个函数指针指向了一个函数&#xff0c;这个函数的参数是两个void*类型的指针&#xff0c;返回类…

【C语言】常见字符串函数的功能与模拟实现

目录 1.strlen() 模拟实现strlen() 2.strcpy() 模拟实现strcpy() 3.strcat() 模拟实现strcat() 4.strcmp() 模拟实现strcmp() 5.strncpy() 模拟实现strncpy() 6.strncat() 模拟实现strncat() 7.strncmp() 模拟实现strncmp() 8.strstr() 模拟实现strstr() 9.str…

数据密集型应用系统设计

数据密集型应用系统设计 原文完整版PDF&#xff1a;https://pan.quark.cn/s/d5a34151fee9 这本书的作者是少有的从工业界干到学术界的牛人&#xff0c;知识面广得惊人&#xff0c;也善于举一反三&#xff0c;知识之间互相关联&#xff0c;比如有个地方把读路径比作programming …

基于 Python 的大数据的电信反诈骗系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

three.js 箭头ArrowHelper的实践应用

效果&#xff1a; 代码&#xff1a; <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red"></div></div></el-main></…

Linux系统安全:安全技术 和 防火墙

一、安全技术 入侵检测系统&#xff08;Intrusion Detection Systems&#xff09;&#xff1a;特点是不阻断任何网络访问&#xff0c;量化、定位来自内外网络的威胁情况&#xff0c;主要以提供报警和事后监督为主&#xff0c;提供有针对性的指导措施和安全决策依据,类 似于监控…

【Java】零基础蓝桥杯算法学习——二分查找

算法模板一: // 数组arr的区间[0,left-1]满足arr[i]<k,[left,n-1]满足arr[i]>k;Scanner scan new Scanner(System.in);int[] arr {1,2,3,4,5};int left 0,right arr.length-1;int k scan.nextInt();while(left<right) {//leftright时退出循环int mid (leftrigh…

Hadoop:认识MapReduce

MapReduce是一个用于处理大数据集的编程模型和算法框架。其优势在于能够处理大量的数据&#xff0c;通过并行化来加速计算过程。它适用于那些可以分解为多个独立子任务的计算密集型作业&#xff0c;如文本处理、数据分析和大规模数据集的聚合等。然而&#xff0c;MapReduce也有…

开源免费的Linux服务器管理面板分享

开源免费的Linux服务器管理面板分享 一、1Panel1.1 1Panel 简介1.2 1Panel特点1.3 1Panel面板首页1.4 1Panel使用体验 二、webmin2.1 webmin简介2.2 webmin特点2.3 webmin首页2.4 webmin使用体验 三、Cockpit3.1 Cockpit简介3.2 Cockpit特点3.3 Cockpit首页3.4 Cockpit使用体验…

算法沉淀——栈(leetcode真题剖析)

算法沉淀——栈 01.删除字符串中的所有相邻重复项02.比较含退格的字符串03.基本计算器 II04.字符串解码05.验证栈序列 栈&#xff08;Stack&#xff09;是一种基于先进后出&#xff08;Last In, First Out&#xff0c;LIFO&#xff09;原则的数据结构。栈具有两个主要的操作&am…

宿舍报修|宿舍报修小程序|基于微信小程序的宿舍报修系统的设计与实现(源码+数据库+文档)

宿舍报修小程序目录 目录 基于微信小程序的宿舍报修系统的设计与实现 一、前言 二、系统功能设计 三、系统实现 1、学生信息管理 2 维修人员管理 3、故障上报管理 4、论坛信息管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设选题推…

算法学习——LeetCode力扣贪心篇1

算法学习——LeetCode力扣贪心篇1 455. 分发饼干 455. 分发饼干 - 力扣&#xff08;LeetCode&#xff09; 描述 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[…

蓝桥杯电子类单片机提升一——超声波测距

前言 单片机资源数据包_2023 一、超声波测距原理 二、超声波测距的应用 1.超声波的发射 2.单片机知识补充&#xff1a;定时器 3.超声波的接收与计时 4.距离的计算 1&#xff09;定时器1为16位自动重载&#xff0b;1T11.0592MHz 2&#xff09;定时器1为16位自动重载&am…

vscode运行C/C++时候cmd.exe界面显示

写了一些命令行传参的程序&#xff0c;需要终端输入参数&#xff0c;默认是输出结果显示在它自己的终端界面 Code-runner: Run In Terminal 打勾就行 效果&#xff1a;

从0开始图形学(光栅化)

前言 说起图形学&#xff0c;很多人就会提到OpenGL&#xff0c;但其实两者并不是同一个东西。引入了OpenGL加重了学习的难度和成本&#xff0c;使得一些原理并不直观。可能你知道向量&#xff0c;矩阵&#xff0c;纹理&#xff0c;重心坐标等概念&#xff0c;但就是不知道这些概…