【C/C++】内存对齐(超详细,看这一篇就够了)
目录
一、为什么要内存对齐
二、基本变量类型所占大小
三、影响内存对齐的情况
四、先说结论(重要)
五、举亿点例子(以下内容均实际运行过,质量保证)
例1:研究结构体最后一个成员内存对齐问题1
例2:研究结构体最后一个成员内存对齐问题2
例3: 研究数组的内存对齐
例4:枚举 & 研究数组之间的内存对齐
例5:结构体嵌套1
例6:结构体嵌套2
例7:__attribute__((packed))
例8:#pragma pack (n)
写在前面:本次实验所用到的环境:Windows 10 Visual Studio(64 位)、Ubuntu 18.04 x86_64-linux-gnu(64 位)!!
一、为什么要内存对齐
简单来说,就是方便计算机去读写数据。
对齐的地址一般都是 n(n = 2、4、8)的倍数。
(1). 1 个字节的变量,例如 char 类型的变量,放在任意地址的位置上;
(2). 2 个字节的变量,例如 short 类型的变量,放在 2 的整数倍的地址上;
(3). 4 个字节的变量,例如 float、int 类型的变量,放在 4 的整数倍地址上;
(4). 8 个字节的变量,例如 long long、double 类型的变量,放在 8 的整数倍地址上;
二、基本变量类型所占大小
注:蓝色标记部分特别注意!!
数据类型 | ILP32(32位Linux系统) | LP64(大部分64位Linux系统) | LLP64(64位Windows系统) |
---|---|---|---|
char | 1 字节 | 1 字节 | 1 字节 |
short | 2 字节 | 2 字节 | 2 字节 |
int | 4 字节 | 4 字节 | 4 字节 |
float | 4 字节 | 4 字节 | 4 字节 |
long | 4 字节 | 8 字节 | 4 字节 |
double | 8 字节 | 8 字节 | 8 字节 |
long long | 8 字节 | 8 字节 | 8 字节 |
指针 point | 4 字节 | 8 字节 | 8 字节 |
枚举 enum | 4 字节 | 4 字节 | 4 字节 |
联合体 union | 取 union 中最大一个变量类型大小 | 取 union 中最大一个变量类型大小 | 取 union 中最大一个变量类型大小 |
ILP32 指 int,long、point 是 32 位。
LP64 指 long、point 是 64 位。
LLP64 指 long long、point 是 64 位。
三、影响内存对齐的情况
1、变量排列顺序。
2、__attribute__((packed)):取消变量对齐,按照实际占用字节数对齐(就是让变量之间排列紧密,不留缝隙)。(gcc才支持)详见例7。
3、#pragma pack (n):让变量强制按照 n 的倍数进行对齐,并会影响到结构体结尾地址的补齐(详见四的通常情况下关于结尾地址补齐的描述)。详见例8。
四、先说结论(重要)
下面的结论均为系统默认对齐规则下进行的:
通常情况:我总结的规律如下:结构体中间:各结构体的起始地址按照各个类型变量默认规则进行摆放,但除了 char 类型变量(详见一),char 类型变量一般遵循 2 的倍数地址开始存储。详见例2。结构体最后(重要):视结构体中最大类型是哪一个,如果是像 int 类型那样是 4 个字节的,并且结构体的结尾地址不满足 4 的倍数的话,向离最近的 4 的倍数地址补齐;如果是像 double 类型那样是 8 个字节的,并且结构体的结尾地址不满足 8 的倍数的话,向离最近的 8 的倍数地址补齐;以此类推。。。。
结构体嵌套:子结构体的成员变量起始地址要视子结构体中最大变量类型决定,比如 struct a 含有 struct b,b 里有 char,int,double 等元素,那 b 应该从 8 的整数倍开始存储。详见例5、例6。
含数组成员:比如 char a[5],它的对齐方式和连续写 5 个 char 类型变量是一样的,也就是说它还是按一个字节对齐。详见例1、例2、例3、例4、例5。
含联合体(union)成员:取联合体中最大类型的整数倍地址开始存储。详见例5。
个人总结能力有限,还是观看例子更容易理解:
五、举亿点例子(以下内容均实际运行过,质量保证)
没有特别标注就是 64 位!!
例1:研究结构体最后一个成员内存对齐问题1
struct stu1 {char a[18];double b;char c;int d;short e;
};
Windows 10:48 字节 Ubuntu 18.04:48 字节
例2:研究结构体最后一个成员内存对齐问题2
struct stu1 {char a[18];int b[3];short c;char d;int e;short f;
};
Windows 10:44 字节 Ubuntu 18.04:44 字节
例3: 研究数组的内存对齐
struct stu1 {int a;char b[8];float c;short d;
};
Windows 10:20 字节 Ubuntu 18.04:20 字节
例4:枚举 & 研究数组之间的内存对齐
enum DAY {MON = 1, TUE, WED, THU, FRI, SAT, SUN
};
struct stu1 {char a[5];char b[3];enum DAY day;int *c;short d;int e;
};
Windows 10:32 字节 Windows 10(32位):24 字节 Ubuntu 18.04:32 字节
64位:
32位:
例5:结构体嵌套1
struct stu2 {char x;int y;double z;char v[6];
};
struct stu1 {union u1 {int a1;char a2[5];}a;struct stu2 b;int c;
};
Windows 10:40 字节 Ubuntu 18.04:40 字节
例6:结构体嵌套2
struct stu2 {char x;int y;double z;char v[6];
};
struct stu1 {char a;struct stu2 b;int c;
};
Windows 10:40 字节 Ubuntu 18.04:40 字节
例7:__attribute__((packed))
由于 VS 和 VScode 均不支持 __attribute__((packed)) ,于是只使用 gcc 编译。
struct __attribute__((packed)) stu1 { // 取消内存对齐char a;long b;short c;float d;int e;
};
Ubuntu 18.04:19 字节
例8:#pragma pack (n)
#pragma pack (2) // 强制以 2 的倍数进行对齐
struct stu1 {short a;int b;long c;char d;
};
#pragma pack () // 取消强制对齐,恢复系统默认对齐
Windows 10:12 字节 Ubuntu 18.04:16 字节
正常情况:
Windows 10:
Ubuntu 18.04:
【C/C++】内存对齐(超详细,看这一篇就够了)相关推荐
- 7种垃圾收集器与内存分配策略,看这一篇就够了
垃圾收集器与内存分配策略-垃圾收集器 (A).图中展示了7种不同分代的收集器: Serial.ParNew.Parallel Scavenge.Serial Old.Parallel Old.CMS. ...
- JVM内存模型,你看这一篇就够了
摘要:JVM是一种用于计算设备的规范,是一个虚构出来的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的. 本文分享自华为云社区<[云驻共创]JVM内存模型的探知之旅>,作者:多米 ...
- python详细安装教程-超详细Python与PyCharm安装教程,看这一篇就够了
原标题:超详细Python与PyCharm安装教程,看这一篇就够了 学习了三天的python, 之前测试一直用课程自带的网页版玩玩, 为了学习 然后就下载了一个python和pycharm 现在分享下 ...
- linux入门_Linux超详细0基础入门篇(一)
首先要感谢大康老师对我在Linux操作系统上的教导. 今天来讲一下用途广泛的Linux的基础入门教程 仅仅是做入门使用,如果想更加深入的学习那就需要自己做探索了. 本次例子使用的是kali linux ...
- 23上教资开始注册!详细报名流程看这一篇就够了!(建议收藏)
注意!2023年1月12日部分省份如:河北.上海.浙江.湖北.湖南.海南.云南.四川.重庆已经可以注册教资笔试了!注册网址:中国教育考试网,选择对应省份进入即可查看是否可以注册! 提示:注册未开启的将 ...
- windows系统 电脑系统重装详细教程(看这一篇就够了)
windows系统 U盘制作 电脑系统重装详细教程(看这一篇就够了) 电脑装机教程 安装前准备 安装步骤如下 第一步:安装软碟通软件 第二步:下载windows系统镜像 第三步:打开软碟通软件 系统盘 ...
- 超详细软件著作权申请——流程篇
超详细软件著作权申请--流程篇 最近写完软件,需要申请软件著作权,费了很多时间了解如何申请,如何撰写申请资料,分成两篇文章特别记录下来--流程篇和材料篇,详细指导各位兄弟再次申请时参考. 文章目录 超 ...
- AJAX(看这一篇就够了,详细)
看这一篇就够了!-Ajax概念详解 AJAX简介: AJAX即Asynchronous JavaScript and XML(异步JavaScript和XML技术),是一种在无须重新加载整个网页的情况 ...
- 阿里大师总结的Web安全超全知识点,看这一篇就够了
安全是互联网公司的生命,也是每一位网民的基本需求. 但根据<2021上半年中国互联网安全报告>,我国Web攻击.恶意爬虫攻击量连年翻倍增长,Web安全根本不能得到正常保障. 由此可见,We ...
- 深度好文:云网络丢包故障定位,看这一篇就够了~
深度好文:云网络丢包故障定位,看这一篇就够了~ https://mp.weixin.qq.com/s/-Q1AkxUr9xzGKwUMV-FQhQ Alex 高效运维 今天 来源:本文经授权转自公众号 ...
最新文章
- 应用DIV+CSS编码时容易犯的一些错误
- 用MySQL创建数据库和数据库表
- 1038 Recover the Smallest Number (30 分)【难度: 中 / 知识点: 贪心 思维】
- 大数据WEB阶段(十八)数据库事务
- CentOS 7 巨大变动之 systemd 取代 SysV的Init
- iOS 面试题分析(二)
- 单片机程序加解密方法和注意事项
- 2021年社招字节跳动测试开发工程师面试题
- lbp纹理特征 MATLAB,毕业设计整理(六):LBP纹理特征
- python实现抠图_python和opencv实现抠图
- 公众号开发小技能:解决模板消息(业务通知)的日调用上限问题
- WTS:基于Web的Terminal控制台
- 交通锥,又称锥形路标、锥形筒、红帽子、方尖碑,是一种道路交通隔离警戒设施。
- 前端网页打印插件print.js
- c语言定义未知长度一维数组,c++ 如何定义未知元素个数的数组
- Introduce Python to data sience/Python 在数据科学中的应用
- 布朗大学计算机专业怎么样,数学差的人不配学计算机?布朗大学教授告诉你一毛钱关系都没有...
- koa +ts 搭建简单项目
- python 理论基础知识试题_Python理论基础知识复习
- 计算机网络信息安全管理办法,计算机网络信息安全管理实施细则.doc