C++内存模型

news2024/9/28 19:15:32

目录

内存模型分类

堆和栈的区别

C++中new的工作过程

堆和栈的区别

为什么堆区要比栈区大


内存模型分类

  • 文本段(ELF)(数据区):主要用于存放我们编写的代码,但是不是按照代码文本的形式存放,而是将代码文本编译成二进制代码,存放的是二进制代码,在编译时就已经确定这个区域存放的内容是什么了,并且这个区域是只读区域;
  • DATA段(初始化静态区,常量区):这个区域主要用于存放编译阶段(非运行阶段时)就能确定的数据,也就是初始化的静态变量、全局变量和常量,这个区域是可读可写的。这也就是我们通常说的静态存储区;
  • BSS段(静态区):这个区域存放的是未曾初始化的静态变量、全局变量,但是不会存放常量,因为常量在定义的时候就一定会赋值了。未初始化的全局变量和静态变量,编译器在编译阶段都会将其默认为0;
  • HEAP(堆):这个区域实在运行时使用的,主要是用来存放程序员分配和释放内存,程序结束时操作系统会对其进行回收,(程序员分配内存像malloc、free、new、delete)都是在这个区域进行的;
  • STACK(栈):存放函数的参数值和局部变量,这个区域的数据是由编译器来自己分配和释放的,只要执行完这个函数,那么这些参数值和变量都会被释放掉;
  • 内核空间(env)环境变量:这个区域是系统内部的区域,我们是不可编辑的;

堆和栈的区别

C++中new的工作过程

申请的是普通的内置类型的空间:

(1)调用 C++标准库中 operator new函数,传入大小。(如果申请的是0byte则强制转化成1byte)

(2)申请相对应的空间,如果没有足够的空间或其他问题且没有定义_new_hanlder,那么会抛出bad_alloc的异常并结束程序,如果定义了_new_hanlder回调函数,那么会一直不停的调用这个函数直到问题被解决为止

(3)返回申请到的内存的首地址.

申请的是类空间:

(1)如果是申请的是0byte,强制转换为1byte

(2)申请相对应的空间,如果没有足够的空间或其他问题且没有定义_new_hanlder,那么会抛出bad_alloc的异常并结束程序

(3)如果定义了_new_hanlder回调函数,那么会一直不停的调用这个函数直到问题被解决为止。

(4)如果这个类没有定义任何构造函数,析构函数,且编译器没有合成,那么下面的步骤跟申请普通的内置类型是一样的。

(5)如果有构造函数或者析构函数,那么会调用一个库函数,具体什么库函数依编译器不同而不同,这个库函数会回调类的构造函数。

(6)如果在构造函数中发生异常,那么会释放刚刚申请的空间并返回异常

(7)返回申请到的内存的首地址

delete 与new相反,会先调用析构函数再去释放内存(delete 实际调用 operator delete)

operator new[]的形参是 sizeof(T)*N+4就是总大小加上一个4(用来保存个数);空间中前四个字节保存填充长度。然后执行N次operator new

operator delete[] 类似;

堆和栈的区别

全局数据区存放静态数据、全局变量、常量。

代码区存放所有类成员函数和非成员函数的代码。

栈区存放用于函数的返回地址、形参、局部变量、返回类型。

堆区存放余下的内存(new和delete)。

  1. 申请方式不同:栈是系统自动分配,堆是程序员申请。
  2. 系统响应不同:
  • 栈:只要栈的剩余空间大于所申请的空间,系统就会为程序提供内存,否则栈溢出。
  • 堆:系统收到申请空间的请求后,会遍历一个操作系统用于记录内存空闲地址的链表,当找到一个空间大于所申请空间的堆结点后,就会为该结点从记录内存空闲地址的链表中删除,并将该结点的内存分配给程序,然后在这块内存区域的首地址处记录分配的大小,这样我们在使用delete来释放内存的时候,delete才能正确地识别并删除该内存区域的所有变量。另外,我们申请的内存空间与堆结点的内存空间不一定相等,这是系统会自动将堆结点上多出来的那部分内存空间回收到空闲链表中。空间大小不同:栈是一块连续的区域,大小一般是1~2M;堆是不连续的区域,空间很大,上限取决于有效的虚拟内存。
  1. 碎片问题:栈是后进先出的队列,内存是连续的,而堆则在多次的new和delete后会产生很多碎片。
  2. 生长方向:栈是向下,堆是向上。
  3. 分配方式:堆是动态分配,没有静态分配。栈是静态分配和动态分配,静态分配由编译器完成,例如局部变量的内存分配;动态分配则由alloca函数分配,不同于堆的手工释放,它的分配是完全由编译器自动释放。
  4. 分配效率:栈是系统的底层数据结构,由专门的寄存器存放栈的地址,专门指令执行压栈出栈,这就决定了栈的效率比较高。而堆是C++函数库提供的,机制复杂,效率低。

为什么堆区要比栈区大

堆干很多事情例如在new一个对象的时候就在堆内存中分配的,那么堆内存是如何管理的呢?堆内存空余内存地址是一个链表的结构存储的,当一个程序请求过来的时候(此时所需的内存大小已经计算好),就会开始遍历这个链表找个比这个程序所需内存大的节点用来给你程序执行所用,此时就会在链表的节点上删除这个即将被占用的内存节点,因为new对象的这个过程是比较缓慢的而且链表上的每个节点内存大小也是不确定的所以就会产生内存碎片,不过用起来非常方便。


 

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

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

相关文章

MySQL的日志undolog、binlog、redolog

1. 日志层次 binlog是Server层,undolog和redolog是innodb引擎层特有的。 2. 记录了什么 & 作用 binlog 记录了所有数据库结构变更和表数据修改的SQL日志。 主要用于数据备份和主从复制,比如误删数据了可以用binlog找回。 undolog 如下图&#…

测试一下阿里通义千问-7B-Chat的性能

测试一下阿里通义千问-7B-Chat的性能 0. 背景1. 实际测试结果(截图) 0. 背景 为了了解一下阿里通义千问-7B-Chat的性能,出了几个问题测试一下。 1. 实际测试结果(截图) 示例代码, import os import openaifrom dotenv import load_dotenv, find_dote…

gma 2 教程(二)数据操作:6.NumPy数组交互

gma 栅格数据集可以通过 ToArray 方法将栅格数据转为NumPy数组,也提供将NumPy数据转换为栅格数据(集)的方法。 读取NumPy数组到数据集 (一)函数简介   (二)示例 保存NumPy数组到文件 &…

基于热交换算法优化的BP神经网络(预测应用) - 附代码

基于热交换算法优化的BP神经网络(预测应用) - 附代码 文章目录 基于热交换算法优化的BP神经网络(预测应用) - 附代码1.数据介绍2.热交换优化BP神经网络2.1 BP神经网络参数设置2.2 热交换算法应用 4.测试结果:5.Matlab代…

leetcode496. 下一个更大元素 I 【单调栈】

【简单题】&#xff08;暴力遍历法很简单&#xff09;但是时间复杂度很高&#xff0c;n的立方级别了。。。 代码&#xff1a; class Solution { public:vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {vector<int&g…

Vue2向Vue3过度核心技术computed计算属性

目录 1 computed计算属性1.1 概念1.2 语法1.3 注意1.4.案例1.5.代码准备 2 computed计算属性 VS methods方法2.1 computed计算属性2.2 methods计算属性2.3 计算属性的优势2.4 总结 3 计算属性的完整写法 1 computed计算属性 1.1 概念 基于现有的数据&#xff0c;计算出来的新属…

抓包相关,抓包学习

检查网络流量 - 提琴手经典 (telerik.com) Headers Reference - Fiddler Classic (telerik.com) 以上是fiddler官方文档 F12要勾选保留日志 不勾选的话跳转到新页面之前页面的日志不会在下方显示 会保留所有抓到的包 如果重定向到别的页面 F12抓包可能看不到响应信息,但是…

在Jupyter Notebook中添加Anaconda环境(内核)

在使用前我们先要搞清楚一些事&#xff1a; 我们在安装anaconda的时候它就内置了Jupyter Notebook&#xff0c;这个jupyter初始只有base一个内核&#xff08;显示为Python3&#xff09; 此后其实我们就不需要重复安装完整的jupyter notebook了&#xff0c;只要按需为其添加新的…

Nexus 如何配置匿名用户访问一个仓库

现在有这样一个需求&#xff0c;我们需要匿名用户访问 Nexus 的一个公共仓库。 设置 Roles 在满足这个需求之前&#xff0c;我们需要设置一个 Roles。 Role 的名字是可以随填写的。 这里关键的问题在你需要访问的仓库的 View 的权限需要设置 Read 和 Browse 这 2 个权限。 如…

保姆级使用vmware安装Ubuntu-server版

保姆级VMware安装Ubuntu20服务器版 文章目录 保姆级VMware安装Ubuntu20服务器版前期准备一、安装vmware二、下载Ubuntu镜像 VMware安装Ubuntu201. 启动Workstation Pro或者Workstation Player,进入软件后新建一个虚拟机2. 进入引导界面选择默认的即可3. 点击下一步即可4. 选择操…

【HSPCIE仿真】HSPICE仿真基础

HSPICE概述 1. HSPICE简介3. 标准输入文件4. 标准输出文件3. HSPCIE仿真过程 1. HSPICE简介 SPICE &#xff08;Simulation Program with IC Emphasis&#xff09;是1972 年美国加利福尼亚大学柏克莱分校电机工程和计算机科学系开发 的用于集成电路性能分析的电路模拟程序。 …

4.1011

目录 四次挥手中收到乱序的FIN包会如何处理&#xff1f; 在 TIME_WAIT 状态的 TCP 连接&#xff0c;收到 SYN 后会发生什么&#xff1f; 四次挥手中收到乱序的FIN包会如何处理&#xff1f; 如果FIN报文比数据包先道道客户端&#xff0c;此时FIN是一个乱序报文&#xff0c;此时…

双向交错CCM图腾柱无桥单相PFC学习仿真与实现(3)硬件功能实现

前言 前面介绍了双向交错CCM图腾柱的系统设计仿真实现&#xff0c;仿真很理想 双向交错CCM图腾柱无桥单相PFC学习仿真与实现&#xff08;1&#xff09;系统问题分解_卡洛斯伊的博客-CSDN博客 然后又介绍了SOG锁相环仿真实现的原理 双向交错CCM图腾柱无桥单相PFC学习仿真与实…

Python项目开发案例————学生信息管理系统(附源码)

一、学生信息管理系统 本文使用Python语言开发了一个学生信息管理系统&#xff0c;该系统可以帮助教师快速录入学生的信息&#xff0c;并且对学生的信息进行基本的增、删、改、查操作&#xff1b;还可以实时地将学生的信息保存到磁盘文件中。 1.1 需求分析 为了顺应互联网时代…

ELK + Kibana + Logstash实现可视化日志

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;elasticsearch、kibana、logstash、日志收集、日志可视化☀️每日 一言&#xff1a;坚持就是胜利啊&#xff0c;哥~ 一、前言 面试官&#xff1a;在日常开发工作中你们是如何查看日志的呢&#x…

9.2 互补功率放大电路

目前使用最广泛的是无输出变压器的功率放大电路&#xff08;OTL 电路&#xff09;和无输出电容的功率放大电路&#xff08;OCL 电路&#xff09;。 一、OCL 电路的组成及工作原理 为了消除图9.1.5所示的基本 OCL 电路所产生的交越失真&#xff0c;应当设置合适的静态工作点&a…

SpringBoot入门篇1 - 简介和工程创建

目录 SpringBoot是由Pivotal团队提供的全新框架&#xff0c; 其设计目的是用来简化Spring应用的初始搭建以及开发过程。 1.创建入门工程案例 ①创建新模块&#xff0c;选择Spring初始化&#xff0c;并配置模块相关基础信息 ②开发控制器类 controller/BookController.jav…

改进YOLO系列:9.添加S2Attention注意力机制

添加S2Attention注意力机制 1. S2Attention注意力机制论文2. S2Attention注意力机制原理3. S2Attention注意力机制的配置3.1common.py配置3.2yolo.py配置3.3yaml文件配置1. S2Attention注意力机制论文 论文题目:S 2 -MLPV2: IMPROVED SPATIAL-SHIFT MLP ARCHITECTURE…

【项目实战典型案例】05.前后端分离的好处(发送调查问卷)

目录 一、背景二、思路三、过程1、主要的业务逻辑2、解决问题的思路 四、总结五、面向对象的好处 一、背景 以下流程图是给用户发送调查问的整体流程&#xff0c;将不必要的业务逻辑放到前端进行处理。这样导致逻辑混乱难以维护。前后端分离的其中一个目的是将功能的样式放在了…