回首遥望-C++内存对齐的思考
这一章节主要巩固一下学习C/C++时内存对齐相关的内容!
文章目录
- 什么是内存对齐?
- 为什么要有内存对齐?
- 如何进行内存对齐?
- 致谢:
什么是内存对齐?
这里不提及一堆啰嗦概念,就结合实际出发!在开发C++程序时,与内存接触较多,当定义一个结构体时,我们以为他是XX字节,结果不是,请看下图:

新手刚学习肯定会认为他是6字节,int四个字节,char是1字节,4+1+1=6,但是在VS2022 X64平台默认下,我们看看他是多少字节!
当我们把鼠标悬浮在struct名字上就会自动弹出悬浮框,告诉我们是8Byte!这就是内存对齐从而对结构体大小产生的影响!

其实内存对齐本质上就是,Visual Stdio平台给结构体留了一些空白的Padding间隙!【注意,有时VS的悬浮框的数值不一定准确,可以sizeof打印观看】
为什么要有内存对齐?
先说结论,两个方面:
- 1、为了读写效率
- 2、为了平台兼容性
这里需要对计算机体系有个基本了解,但是不废话,咱们大白话直白平铺。当CPU需要读写内存数据,需要通过地址总线、数据总线的辅助,传递地址数据和获取真正内存数据!不同计算机平台这些所谓的总线宽度是不同的!
假设在大多数32位cpu中,所谓这些总线宽度是32位,也就是4字节长度!也就代表真正一次能够读取的数据最多就是4个字节!
上一段说,既然一次最多读取4个字节数据,那地址的编号,咱们就4个字节依次对地址编号,第1个4个字节内存的地址叫0,第2个4个字节内存的地址叫1,依次递增,如下图:

既然都已经编号成这样了,那你说他可能会访问所谓的0.5地址编号的内存吗?所以这里有两种取舍:
- 1、压根不支持这样读写
- 2、支持,但是需要分两次读写
如果是第一种情况,正好解释了内存对齐原因的第二点:为了平台兼容性!因为只支持4Byte对齐的读写,所以不对齐不行啊,这个理由可否?
咱们来看看第二种情况,咱们假设CPU支持,那么如果要读0.5位置的4Byte数据,CPU怎么办?
其实它还是一样不能直接读取不了0.5位置的数据,但是可以读两次,第一次读0编号,第二次读1编号,最后分别都拿一点数据,然后拼起来!如下图示意:

我们直观的感受到,既要读多次,又要进行数据拆分和拼接的计算过程,很显然,没有一次性直接读出来来的高效!
这也验证了为什么要内存对齐的第一个方面:为了读写效率!
如何进行内存对齐?
这里结合网上的帖子和自己的实验验证,直接给出内存对齐规则以及相应名词介绍!
前置名词介绍:
- 默认对齐系数
- 成员有效对齐值
- 结构体最大对齐值
什么是默认对齐系数?
它是一个数字,每个特定平台的编译器有自己的默认“对齐系数”,这里以Visual Stdio 2022的测试为例,X86默认对齐系数是8,X64默认值是16。
如何查看的呢?通过VS提供的指令:#pragma pack(show) 可以在编译时,作为warning信息显示出,如下图:

什么是成员有效对齐值?
它也是一个数字,以结构体来说,结构体每个成员都有自己的有效对齐值,计算公式:有效对齐值 = min{默认对齐系数, 变量类型字节长度}!
举个例子:

简单易懂,因为int类型,字节长度4,所以有效对齐 = min{4, 16} = 4,16是当前平台的默认对齐系数!
什么是结构体最大对齐值?
它也是一个数字,上一节说了,既然结构体每个成员都有一个有效对齐值,那么最大的那个数字就是结构体最大对齐值!
举个例子:

前置名词介绍完了,咱们上正菜,内存对齐规则:
简单结构体的内存对齐规则:
1、结构体第一个成员的位置偏移为0!
2、结构体非第一个成员的位置偏移,是该成员有效对齐值的整数倍!【因为此限制,自然会和上一变量位置可能有空白Padding】
3、结构体总大小是结构体最大对齐值的整数倍!【因为此限制,结构体末尾是可能存在空白Padding】
举两个例子,辅助大家理解:
例1:

根据规则3,结构体最大对齐值为4,而如果仅仅三个变量大小和为6字节,所以尾部补充2字节的空白Padding!
例2:

应用规则2: 考虑第二个变量int i,因为它的有效对齐值为4字节,所以距离第一个成员留有3字节的空白Padding!
应用规则3: 三个成员+3字节Padding,一共是1 + 3 + 4 + 2 = 10字节,而最大对齐值是4字节,所以尾部补充2字节空白Padding!
上述说的都是不存在结构体复合嵌套的情况,其实嵌套了,规则也是类似,但是有一些需要注明的要求,如下:
嵌套结构体的内存对齐规则补充:
1、结构体第一个成员的位置偏移为0!
2、结构体非第一个成员的位置偏移,是该成员有效对齐值的整数倍!
【如果是结构体类型成员,则该成员的有效对齐值是成员对应结构体类型自身的最大对齐值】
3、结构体总大小是结构体最大对齐值的整数倍!
举两个例子,辅助大家理解:
例1:

T1不多赘述,重点解释下T2中的b成员,也就是嵌套结构体成员类型!
在计算T2的b成员的有效对齐时,它并不是用T1的结构体大小和默认对齐值16取最小值,而是用该结构体类型的最大对齐值和默认对齐值取最小值,也就是T1的最大对齐值8和16取最小值为8作为b成员的有效对齐值!
例2:

大家好好品味品味吧!
致谢:
今天的学习就到此为止啦,喜欢的小伙伴点点关注+赞哦!有问题及时留言!感谢大家Thanks♪(・ω・)ノ!我是火火,火一般的男人!
相关文章:
回首遥望-C++内存对齐的思考
这一章节主要巩固一下学习C/C时内存对齐相关的内容! 文章目录 什么是内存对齐?为什么要有内存对齐?如何进行内存对齐?致谢: 什么是内存对齐? 这里不提及一堆啰嗦概念,就结合实际出发࿰…...
力扣 LeetCode 704. 二分查找(Day1:数组)
解题思路: 二分查找主要分为[ left , right ]左闭右闭和[ left , right )左闭右开两种 此处采取[ left , right ]左闭右闭写法 注意: 1. right的初始化取值 2. while中取等 3. right mid -1 ; class Solution {public int search(int[] nums, i…...
【Mode Management】AUTOSAR架构下唤醒源检测函数EcuM_CheckWakeup详解
目录 前言 正文 1.AUTOSAR标准描述 1.1 EcuM_CheckWakeup用来干什么 1.2 EcuM_CheckWakeup在哪里被调用 1.3 EcuM_CheckWakeup的使用场景 1.3.1 GPT中断检测唤醒源 1.3.2 EcuM轮询GPT检测唤醒源 1.3.3 ICU中断检测唤醒源 1.3.4 其他 2.AUTOSR工具相关配置 3.唤醒源…...
Zabbix基础信息概述
1.Zabbix概述 Zabbix 是一款能够监控各种网络参数以及服务器健康性和完整性的软件。Zabbix 使用灵活的通知机制,允许用户为几乎任何事件配置基于邮件的告警,这样可以快速反馈服务器的问题。基于已存储的数据,Zabbix 提供了出色的报告和数据可…...
SpringBoot(十二)SpringBoot配置redis
接下来我要实现的webscoket即时聊天中需要使用到redis,我先在项目中配置一下redis。 我这里再windows中做测试,关于redis的安装请移步《Redis(三)Windows系统安装redis》 一:在pom.xml中添加依赖 <!-- springboot redis start --><dependency><grou…...
Pycharm安装
Pycharm安装 返回主目录Pycharm安装1. Pycharm下载PyCharm官网下载地址下载安装包 2. Pycharm安装第一步:双击安装包第二步:进入安装程序第三步:选择安装路径第四步:选择安装选项第五步:安装第六步:完成安装…...
OpenAI大改下代大模型方向,scaling law撞墙?AI社区炸锅了
有研究预计,如果 LLM 保持现在的发展势头,预计在 2028 年左右,已有的数据储量将被全部利用完。届时,基于大数据的大模型的发展将可能放缓甚至陷入停滞。 来自论文《Will we run out of data? Limits of LLM scaling based on hum…...
技术整合与生态构建:Lyft与Mobileye引领自动驾驶新纪元
在科技日新月异的今天,自动驾驶技术正逐渐从科幻电影走进现实生活,成为出行服务领域的一股不可忽视的力量。近日,北美网约车巨头Lyft与自动驾驶技术领先者Mobileye宣布联手合作,共同推动自动驾驶汽车出行服务的广泛商业化进程。此…...
利用huffman树实现对文件A先编码后解码
利用huffman树实现对文件A先编码后解码,范围为ASCII码0-255的值,如何解决特殊符号问题是一个难点,注意应使用unsigned char存储数据,否则ASCII码128-255的值可能会出问题: #define _CRT_SECURE_NO_WARNINGS 1 #includ…...
第三十九章 基于VueCli自定义创建项目
目录 1. 选择创建模式 2. 选择需要的功能 3. 选择历史模式还是哈希模式 4.CSS预处理器 5. 选择ESLint规则 6. 开始创建项目 7. 自定义项目最终结构 1. 选择创建模式 输入创建的项目名,创建项目: 这里选择自定义模式: 2. 选择需要…...
网页web无插件播放器EasyPlayer.js点播播放器遇到视频地址播放不了的现象及措施
在数字媒体时代,视频点播已成为用户获取信息和娱乐的重要方式。EasyPlayer.js作为一款流行的点播播放器,以其强大的功能和易用性受到广泛欢迎。然而,在使用过程中,用户可能会遇到视频地址无法播放的问题,这不仅影响用户…...
LLaMA-Factory学习笔记(1)——采用LORA对大模型进行SFT并采用vLLM部署的全流程
该博客是我根据自己学习过程中的思考与总结来写作的,由于初次学习,可能会有错误或者不足的地方,望批评与指正。 1. 安装 1.1 LLaMA-Factory安装 安装可以参考官方 readme (https://github.com/hiyouga/LLaMA-Factory/blob/main/…...
PHP和Python脚本的性能监测方案
目录 1. 说明 2. PHP脚本性能监测方案 2.1 安装xdebug 2.2 配置xdebug.ini 2.3 命令行与VS Code中使用 - 命令行 - VS Code 2.4 QCacheGrind 浏览 3. Python脚本性能监测方案 3.1 命令行 4. 工具 5.参考 1. 说明 获取我们的脚本程序运行时的指标,对分析…...
C语言实现数据结构之堆
文章目录 堆一. 树概念及结构1. 树的概念2. 树的相关概念3. 树的表示4. 树在实际中的运用(表示文件系统的目录树结构) 二. 二叉树概念及结构1. 概念2. 特殊的二叉树3. 二叉树的性质4. 二叉树的存储结构 三. 二叉树的顺序结构及实现1. 二叉树的顺序结构2.…...
战略共赢 软硬兼备|云途半导体与知从科技达成战略合作
2024年11月5日,江苏云途半导体有限公司(以下简称“云途”或“云途半导体”)与上海知从科技有限公司(以下简称“知从科技”)达成战略合作,共同推动智能汽车领域高端汽车电子应用的开发。 云途半导体与知从科…...
python:用 sklearn 构建 K-Means 聚类模型
pip install scikit-learn 或者 直接用 Anaconda3 sklearn 提供了 preprocessing 数据预处理模块、cluster 聚类模型、manifold.TSNE 数据降维模块。 编写 test_sklearn_3.py 如下 # -*- coding: utf-8 -*- """ 使用 sklearn 构建 K-Means 聚类模型 "&…...
elementUI中2个日期组件实现开始时间、结束时间(禁用日期面板、控制开始时间不能超过结束时间的时分秒)实现方案
没有使用selectableRange 禁用时分秒,是因为他会禁止每天的时分秒。 我们需要解决的是当开始时间、结束时间是同一天时, 开始时间不能超过结束时间。 如果直接清空,用户体验不好。所以用watch监听赋值,当前操作谁,它不…...
Oracle 聚集因子factor clustering
文章目录 聚集因子(Factor clustering)举例说明查询聚集因子聚集因子的优化结论 最近发现突然忘记聚集因子的原理了,故整理记录一下 聚集因子(Factor clustering) 在Oracle中,聚集因子(Clustering Factor)用于衡量数据在表中存储…...
【大数据学习 | kafka高级部分】kafka的快速读写
1. 追加写 根据以上的部分我们发现存储的方式比较有规划是对于后续查询非常便捷的,但是这样存储是不是会更加消耗存储性能呢? 其实kafka的数据存储是追加形式的,也就是数据在存储到文件中的时候是以追加方式拼接到文件末尾的,这…...
云技术基础
学习视频笔记均来自B站UP主" 泷羽sec",如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 https://space.bilibili.com/350329294* 为什么要学云技术? 无论是防御还是…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
