【C++】讲的最通透最易懂的关于结构体内存对齐的问题
目录
- 1. 内存对齐规则
- 2. 简单易懂的内存对齐示例
- 2.1 简单结构体
- 2.2 含位域的结构体
- 2.3 空类的大小
- 2.4 嵌套结构体
- 3. 为什么需要内存对齐?
- 4. 类型在不同系统下所占字节数
1. 内存对齐规则
- 第一个成员在与结构体变量偏移量为0的位置处。
- 其他成员变量要对齐到某个数字(对其数)的整数倍的地址处。对其数=编译器默认的一个对齐数与该成员大小的较小者。
vs中默认的值是8 Linux中默认的值是4 - 结构体总大小为最大对其数(每一个成员变量都有一个对其数)的整数倍。
- 如果嵌套了结构体对齐到自己的最大对其数是整数倍处,结构体的整体大小就是最大对齐数(含嵌套结构体的对齐数)的整数倍。
- 如对内存对齐有明确要求,可用
#pragma pack(n)指定(n必须是2的N次方),以n和结构体中最长数据成员长度中较小者为有效值
可能只看上面的描述你还是有点搞不懂,那么我们可以看一下具体的例子和视图讲解:
struct s1{char c1;int i;char c2;
};
//结构体总大小为:12

2. 简单易懂的内存对齐示例
2.1 简单结构体
struct s1
{char str; //1字节short x; //2字节int num; //4字节
};
// sizeof(s1) = 8 // (1+1) + 2 + 4 = 8 第2个加1处的内存是空的
2.2 含位域的结构体
一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。
struct s2
{unsigned char a:7; //字段a占用了一个字节的7个bitunsigned char b:2; //字段b占用了2个bitunsigned char c:7; //字段c占用了7个bit
}s1;
// sizeof(s1) = 3 // 1 + 1 + 1 = 3
struct s3
{char t : 4; //4表示在一个字节中占4个比特位char k : 4;
};
// sizeof(s3) = 1 //0.5 + 0.5 = 1
struct s4
{char t : 4; //4表示在一个字节中占4个比特位char k : 4;unsigned short i : 8;char a;
};
// sizeof(s4) = 6 //(0.5 + 0.5 + 1) + 2 + (1+1) = 6
// 解释:0.5和0.5占一个字节,两个占4比特的刚好可以放在一个字节中,short为2字节,对齐数是2,所以0.5 + 0.5 + 1中加的1是空的
2.3 空类的大小
class A {};
// sizeof(A) = 1
空类,没有任何成员变量和成员函数,编译器是支持空类实例化对象的,对象必须要被分配内存空间才有意义,大小: 1Byte (字节)
2.4 嵌套结构体
class A {
private:double dd;int ii;int* pp;
};class Test {
private:int i;A a;double d;char* p;
};
int main()
{A a1;Test test;cout << sizeof(a1) << endl;cout << sizeof(test) << endl;
}
// x86(32位操作系统)平台运行结果:40
// x64(64位操作系统)平台运行结果:48
对其数 = 编译器默认的一个对齐数与该成员大小的较小者,vs中默认的值是8
-
x86:指针是4字节,类A的大小是16,8与16的较小者是8。内存大小为:8 + 16 + 8 + 4 = 36,又因为36不是最大对齐数8的倍数,所以内存向后偏移,大小为 40
-
x64:指针是8字节,类A大小为24,8与24的较小者是8。内存大小为:8 + 24 + 8 +8 = 48,48刚好是最大对齐数8的倍数,所以内存大小为48
3. 为什么需要内存对齐?
字节对齐主要是为了提高内存的访问效率
cpu一次能读取多少内存要看数据总线是多少位,如果是16位,则一次只能读取2个字节,如果是32位,则可以读取4个字节,并且cpu不能跨内存区间访问。
假设有这样一个结构体如下:
struct s
{char a;int b;
};
假设地址空间是类似下面这样的:

-
在没有字节对齐的情况下,变量a就是占用了
0x00000001这一个字节,而变量b则是占用了0x00000002~0x000000005这四个字节,那么cpu如果想从内存中读取变量b,首先要从变量b的开始地址0x00000002读到0x0000004,然后再读取一次0x00000005这个字节,相当于读一个int,cpu从内存读取了两次。 -
而如果进行字节对齐的话,变量a还是占用了
0x00000001这一个字节,而变量b则是占用了0x00000005~0x00000008这四个字节,那么cpu要读取变量b的话,就直接一次性从0x00000005读到0x00000008,就一次全部读取出来了。 -
所以说,字节对齐的根本原因其实在于cpu读取内存的效率问题,对齐以后,cpu读取内存的效率会更快。结构体的内存对齐是拿空间来换取时间的做法
4. 类型在不同系统下所占字节数
| 类型 | win32 | win64 | linux32 | linux64 |
|---|---|---|---|---|
| char | 1 | 1 | 1 | 1 |
| short | 2 | 2 | 2 | 2 |
| int | 4 | 4 | 4 | 4 |
| long | 4 | 4 | 4 | 8 |
| long long | 8 | 8 | 8 | 8 |
| float | 4 | 4 | 4 | 4 |
| double | 8 | 8 | 8 | 8 |
| void*(指针) | 4 | 8 | 4 | 8 |

相关文章:
【C++】讲的最通透最易懂的关于结构体内存对齐的问题
目录1. 内存对齐规则2. 简单易懂的内存对齐示例2.1 简单结构体2.2 含位域的结构体2.3 空类的大小2.4 嵌套结构体3. 为什么需要内存对齐?4. 类型在不同系统下所占字节数1. 内存对齐规则 第一个成员在与结构体变量偏移量为0的位置处。其他成员变量要对齐到某个数字&a…...
Stochastic Approximation 随机近似方法的详解之(一)
随机近似的定义:它指的是一大类随机迭代算法,用于求根或者优化问题。 Stochastic approximation refers to a broad class of stochastic iterative algorithms solving root finding or optimization problems. temporal-difference algorithms是随机近…...
软件自动化测试工程师面试题集锦
以下是部分面试题目和我的个人回答,回答比较简略,仅供参考。不对之处请指出 1.自我介绍 答:姓名,学历专业,技能,近期工作经历等,可以引导到最擅长的点,比如说代码或者项目 参考&a…...
智合同丨教你做一个懂AI的法律人
作为一名法律人,合同审核工作是日常工作中最基本也是必不可少的一项事务。我们知道,一般在企业,合同审批会涉及到众多部门和职务角色,最关键的一环其实在法务或者律师建议,其他部门给出的审批意见基本上都是基于自己部…...
如何判断自己使用的IP是独享还是共享?
在互联网上,我们常常听到独享IP和共享IP这两个概念。独享IP指的是一个IP地址只被一个用户或一个网站所使用,而共享IP则是多个用户或多个网站共用一个IP地址。那么,如何分辨IP是不是独享呢?接下来,我们将从几个方面来看。在这之前…...
跳石头
题目描述 一年一度的"跳石头"比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有 N 块岩石(不含起点和终点的岩石)。在比赛过程中,选手们将从起点出发,每一步跳…...
上传gitee教程,Gitee怎么上传代码到仓库
目录 第一步:配置git的用户名和邮箱 第二步:上传到远程仓库 第三步:将仓库的master分支拉取过来和本地的当前分支进行合并 第四步:将修改的所有代码添加到暂存区 第五步:将缓存区内容添加到本地仓库(…...
netstat命令详解
1、下载netstat命令对应的软件包 yum install net-tools -y2、netsta命令介绍 [rootvm01 ~]# man netstatNETSTAT(8) Linux System Administrators Manual NETSTAT(8)NAMEnetstat - Print network connections, routing t…...
数据库三范式
文章目录数据库三范式1. 第一范式(1NF)2. 第二范式(2NF)3. 第三范式(3NF)数据库三范式 第一范式:有主键,具有原子性,字段不可分割第二范式:完全依赖…...
K8S 1.20 弃用 Docker 评估之 Docker 和 OCI 镜像格式的差别
背景 2020 年 12 月初,Kubernetes 在其最新的 Changelog 中宣布,自 Kubernetes 1.20 之后将弃用 Docker 作为容器运行时。 弃用 Docker 带来的,可能是一系列的改变,包括不限于: 容器镜像构建工具容器 CLI容器镜像仓…...
Vue2和Vue3响应式的区别
数据响应式是什么? 所谓 数据响应式 就是建立 响应式数据 与 依赖(调用了响应式数据的操作)之间的关系,当响应式数据发生变化时,可以通知那些使用了这些响应式数据的依赖操作进行相关更新操作,可以是DOM…...
模型实战(6)之Alex实现图像分类:模型原理+训练+预测(详细教程!)
Alex实现图像分类:模型原理+训练+预测 图像分类或者检索任务在浏览器中的搜索操作、爬虫搜图中应用较广,本文主要通过Alex模型实现猫狗分类,并且将可以复用的开源模型在文章中给出!!!数据集可以由此下载:Data本文将从以下内容做出讲述: 1.模型简介及环境搭建2.数据集准…...
【大数据】最全的大数据Hadoop|Yarn|Spark|Flink|Hive技术书籍分享/下载链接,持续更新中...
这里写目录标题Hadoop大数据处理Hadoop技术内幕:深入解析YARN架构设计与实现原理Hadoop 技术内幕:深入解析Hadoop Common 和HDFS 架构设计与实现原理Spark SQL内核剖析Hadoop 应用架构深度剖析Hadoop HDFSHadoop实战Hive编程指南Hadoop大数据处理 本书以…...
RIG Exploit Kit 仍然通过 IE 感染企业用户
RIG Exploit Kit 正处于最成功的时期,每天尝试大约 2000 次入侵并在大约 30% 的案例中成功,这是该服务长期运行历史中的最高比率。 通过利用相对较旧的 Internet Explorer 漏洞,RIG EK 已被发现分发各种恶意软件系列,包括 Dridex…...
GIS在地质灾害危险性评估与灾后重建中的实践技术应用及python机器学习灾害易发性评价模型建立与优化进阶
地质灾害是指全球地壳自然地质演化过程中,由于地球内动力、外动力或者人为地质动力作用下导致的自然地质和人类的自然灾害突发事件。由于降水、地震等自然作用下,地质灾害在世界范围内频繁发生。我国除滑坡灾害外,还包括崩塌、泥石流、地面沉…...
SQL SERVER中SCHEMA的詳解
SQL SERVER中SCHEMA的講解1. Introduction1.1 優勢1.2 內置schema2. Create Schema2.1 Parameters2.2 Sql3.Awakening1. Introduction 1.1 優勢 数据库模式为我们提供了在数据库中创建逻辑对象组的灵活性。如果多个团队使用同一个数据库,我们可以设计各种模式来分組…...
【LeetCode】剑指 Offer(13)
目录 题目:剑指 Offer 31. 栈的压入、弹出序列 - 力扣(Leetcode) 题目的接口: 解题思路: 代码: 过啦!!! 写在最后: 题目:剑指 Offer 31. 栈…...
帮助小型企业实现业务增长的7种数字营销策略
数字营销一直在不断地变化和发展,在过去的几年里我们已经见识到了其迅猛的发展速度。虽然我们在数字营销中看到了一些新的趋势,但对于小型企业来说很难利用并发挥其优势。相比较大型企业,小型企业的预算和资源通常有限,所以他们很…...
互联网行业的高级产品经理和普通产品经理有哪些区别?
普通产品经理的一天可能是这样的。 早上到公司想一想,这几天有哪些事情要处理。打开记事本,按照上面要求的任务一条一条开始做。 这里有个需求,是要给产品的聊天模块增加历史记录。嗯,看一下常见的几款社交工具 APP,他…...
aardio - 【库】简单信息框
昨晚得知aardio作者一鹤的妻子病情严重,深感悲痛。今日给一鹤捐赠少许,望其妻能挺过难关,早日康复。 aardio是一个很好的编程工具,我非常喜欢,这两年也一直在用。虽然未曾用其获利,但其灵活的语法ÿ…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁
赛门铁克威胁猎手团队最新报告披露,数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据,严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能,但SEMR…...
