当前位置: 首页 > news >正文

C++初学者指南第一步---10.内存(基础)

C++初学者指南第一步—10.内存(基础)

文章目录

  • C++初学者指南第一步---10.内存(基础)
    • 1.内存模型
      • 1.1 纸上谈兵:C++的抽象内存模型
      • 1.2 实践:内存的实际处理
    • 2. 自动存储
    • 3.动态存储:std::vector
      • 3.1 动态内存分配
      • 3.2 std::vector 内存布局
      • 3.3 std::vector 扩容方案
      • 3.4 std::vector的大小(size)和容量(capacity)
      • 3.5 std::vector内存生命周期示例

1.内存模型

1.1 纸上谈兵:C++的抽象内存模型

C++ 的语言规范基于抽象内存模型。
具体实现(编译器,C++运行时等)可以采用不同策略来满足具体平台(CPU架构,操作系统等)上的这些规范。
内存组织
在这里插入图片描述
在这里插入图片描述

示例:std::int16_t i = 1234; 是一个名为 i 的对象,大小为 2 字节(= 16 位),值为 0000010011010010,
根据其类型 int16_t 表示数字 1234。

请注意,抽象模型并没有涉及到内存是如何划分的,也不涉及缓存层次结构。

对象存储持续时间类型

自动对象生存期绑定到 { … } 块作用域的开始到结束局部变量、函数参数
动态通过特殊指令控制对象寿命可以按需创建/销毁且独立于块作用域的对象
线程与线程的开始和结束相关的对象生存期每线程存储
静态对象生存期与程序的开始和结束相关联单例

1.2 实践:内存的实际处理

C++内存模型的实际实现

  • 受到目标平台的功能和限制的限制 (CPU/内存架构、操作系统、编译器)
  • 需要修复C++标准留下的选项,例如字节中的位数(在大多数平台上为8)
  • 需要支持c++标准描述的对象存储期/生命周期方案(自动、动态、线程、静态)

常见的解决方案:自动/动态存储期专用内存分区

HEAP 堆(也被称为自由存储区)

  • 用于动态存储期对象,例如std::vector的内容
  • 空间大:可用于大容量存储(大部分主内存)
  • 根据需要分配和释放任何对象。
  • 无序分配和释放 ⇒ 导致内存碎片化
  • 分配缓慢:需要为新对象找到连续的空置空间

STACK 栈(堆栈)

  • 用于自动存储持续时间局部变量、函数参数的对象等。
  • 空间小(通常只有几 MB)
  • 快速分配:新对象始终放在顶部
  • 以创建的相反顺序释放分配的对象
  • 无法释放分配在最顶部以下的对象 (= 最新)

2. 自动存储

栈通常用于自动存储持续时间的对象如局部变量(包括函数参数):
<1>
在这里插入图片描述
<2>
在这里插入图片描述
<3>
在这里插入图片描述<4>
在这里插入图片描述
<5>
在这里插入图片描述
<6>
在这里插入图片描述
<7>
在这里插入图片描述
<8>
在这里插入图片描述
<9>
在这里插入图片描述
<10>
在这里插入图片描述

3.动态存储:std::vector

3.1 动态内存分配

当前:只使用std::vector
后面:使用更多的标准库容器(set、map…)
再后面:手动动态内存分配
在现代 C++ 中,手动分配内存实际上只有在你想要实现自己的动态数据结构/容器时才是真正必要的。

3.2 std::vector 内存布局

  • 每个向量对象都有一个单独的缓冲区,该缓冲区是动态分配的(在堆上),实际内容存储在其中。
  • 现在我们只知道如何在栈上分配对象,但向量对象 v 本身也可以在堆上分配(更多内容请参阅后面的章节)。
vector<int> v {0,1,2,3,4};

在这里插入图片描述

3.3 std::vector 扩容方案

  • 分配后的内存块无法调整大小!(之前分配的内存块后面不一定有剩余空间)
  • 动态数组实现将数组对象与用于存储值的实际内存块分开。
  • 然后通过以下方式进行扩容:
    1. 动态分配新的、(≈1.1-2×)更大的内存块
    2. 将旧值复制/移动到新块
    3. 释放旧的、较小的内存块
      在这里插入图片描述
      动态数组(维基百科)

3.4 std::vector的大小(size)和容量(capacity)

  • .size()→ 向量中的元素数量
  • .resize(新的元素数量)
  • . capacity() → 可以使用的内存槽数量(容量)
  • .reserve(新的容量)
    在这里插入图片描述
    注意:如果您大概知道元素的数量 ⇒ 在将元素添加到向量之前先进行预留(reserve)!
    这样可以避免在增长阶段时进行不必要的内存分配和复制。

3.5 std::vector内存生命周期示例

<1>
在这里插入图片描述
<2>
在这里插入图片描述
<3>
在这里插入图片描述
<4>
在这里插入图片描述
<5>
在这里插入图片描述
<6>
在这里插入图片描述
<7>
在这里插入图片描述
<8>
在这里插入图片描述
<9>
在这里插入图片描述
<10>
在这里插入图片描述
<11>
在这里插入图片描述
<12>
在这里插入图片描述
<13>
在这里插入图片描述
<14>
在这里插入图片描述
<15>
在这里插入图片描述

附上原文链接
如果文章对您有用,请随手点个赞,谢谢!^_^

相关文章:

  • Hive笔记-3
  • OpenCV--Mat属性和深浅拷贝
  • 前端开发之浏览器垃圾回收机制
  • Redis分片集群搭建
  • springBoot+mongoDB项目中,使用MongoFactory、MongoTemplate分页条件查询,增删查改
  • 代码随想三刷二叉树篇3
  • 代码随想录算法训练营第38天|● 理论基础 ● 509. 斐波那契数● 70. 爬楼梯 ● 746. 使用最小花费爬楼梯
  • Linux:文件描述符
  • ai写诗词,三款软件助你妙笔生花!
  • Cesium4Unreal - # 009 直接加载显示Shapefile
  • 返回给前端数据的封装
  • 【Spine学习13】之 制作受击动画思路总结(叠加颜色特效发光效果)
  • Go 基础丨字符串 string
  • 【已解决】better-scroll在PC端如何开启鼠标滚动以及如何始终显示滚动条
  • Vim基础操作:常用命令、安装插件、在VS Code中使用Vim及解决Vim编辑键盘错乱
  • Angular6错误 Service: No provider for Renderer2
  • C# 免费离线人脸识别 2.0 Demo
  • Docker: 容器互访的三种方式
  • Flex布局到底解决了什么问题
  • Hibernate【inverse和cascade属性】知识要点
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • Java|序列化异常StreamCorruptedException的解决方法
  • JavaScript 基本功--面试宝典
  • JavaScript 基础知识 - 入门篇(一)
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • java正则表式的使用
  • js继承的实现方法
  • Laravel深入学习6 - 应用体系结构:解耦事件处理器
  • spring + angular 实现导出excel
  • windows-nginx-https-本地配置
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 将回调地狱按在地上摩擦的Promise
  • 紧急通知:《观止-微软》请在经管柜购买!
  • 前端工程化(Gulp、Webpack)-webpack
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • #{}和${}的区别是什么 -- java面试
  • #if #elif #endif
  • #ifdef 的技巧用法
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (1)Jupyter Notebook 下载及安装
  • (16)Reactor的测试——响应式Spring的道法术器
  • (3)(3.5) 遥测无线电区域条例
  • (Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (顶刊)一个基于分类代理模型的超多目标优化算法
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (论文阅读11/100)Fast R-CNN
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (四)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (五)c52学习之旅-静态数码管