目录

一、为什么要内存对齐

二、基本变量类型所占大小

三、影响内存对齐的情况

四、先说结论(重要)

五、举亿点例子(以下内容均实际运行过,质量保证)

例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++】内存对齐(超详细,看这一篇就够了)相关推荐

  1. 7种垃圾收集器与内存分配策略,看这一篇就够了

    垃圾收集器与内存分配策略-垃圾收集器 (A).图中展示了7种不同分代的收集器: Serial.ParNew.Parallel Scavenge.Serial Old.Parallel Old.CMS. ...

  2. JVM内存模型,你看这一篇就够了

    摘要:JVM是一种用于计算设备的规范,是一个虚构出来的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的. 本文分享自华为云社区<[云驻共创]JVM内存模型的探知之旅>,作者:多米 ...

  3. python详细安装教程-超详细Python与PyCharm安装教程,看这一篇就够了

    原标题:超详细Python与PyCharm安装教程,看这一篇就够了 学习了三天的python, 之前测试一直用课程自带的网页版玩玩, 为了学习 然后就下载了一个python和pycharm 现在分享下 ...

  4. linux入门_Linux超详细0基础入门篇(一)

    首先要感谢大康老师对我在Linux操作系统上的教导. 今天来讲一下用途广泛的Linux的基础入门教程 仅仅是做入门使用,如果想更加深入的学习那就需要自己做探索了. 本次例子使用的是kali linux ...

  5. 23上教资开始注册!详细报名流程看这一篇就够了!(建议收藏)

    注意!2023年1月12日部分省份如:河北.上海.浙江.湖北.湖南.海南.云南.四川.重庆已经可以注册教资笔试了!注册网址:中国教育考试网,选择对应省份进入即可查看是否可以注册! 提示:注册未开启的将 ...

  6. windows系统 电脑系统重装详细教程(看这一篇就够了)

    windows系统 U盘制作 电脑系统重装详细教程(看这一篇就够了) 电脑装机教程 安装前准备 安装步骤如下 第一步:安装软碟通软件 第二步:下载windows系统镜像 第三步:打开软碟通软件 系统盘 ...

  7. 超详细软件著作权申请——流程篇

    超详细软件著作权申请--流程篇 最近写完软件,需要申请软件著作权,费了很多时间了解如何申请,如何撰写申请资料,分成两篇文章特别记录下来--流程篇和材料篇,详细指导各位兄弟再次申请时参考. 文章目录 超 ...

  8. AJAX(看这一篇就够了,详细)

    看这一篇就够了!-Ajax概念详解 AJAX简介: AJAX即Asynchronous JavaScript and XML(异步JavaScript和XML技术),是一种在无须重新加载整个网页的情况 ...

  9. 阿里大师总结的Web安全超全知识点,看这一篇就够了

    安全是互联网公司的生命,也是每一位网民的基本需求. 但根据<2021上半年中国互联网安全报告>,我国Web攻击.恶意爬虫攻击量连年翻倍增长,Web安全根本不能得到正常保障. 由此可见,We ...

  10. 深度好文:云网络丢包故障定位,看这一篇就够了~

    深度好文:云网络丢包故障定位,看这一篇就够了~ https://mp.weixin.qq.com/s/-Q1AkxUr9xzGKwUMV-FQhQ Alex 高效运维 今天 来源:本文经授权转自公众号 ...

最新文章

  1. 应用DIV+CSS编码时容易犯的一些错误
  2. 用MySQL创建数据库和数据库表
  3. 1038 Recover the Smallest Number (30 分)【难度: 中 / 知识点: 贪心 思维】
  4. 大数据WEB阶段(十八)数据库事务
  5. CentOS 7 巨大变动之 systemd 取代 SysV的Init
  6. iOS 面试题分析(二)
  7. 单片机程序加解密方法和注意事项
  8. 2021年社招字节跳动测试开发工程师面试题
  9. lbp纹理特征 MATLAB,毕业设计整理(六):LBP纹理特征
  10. python实现抠图_python和opencv实现抠图
  11. 公众号开发小技能:解决模板消息(业务通知)的日调用上限问题
  12. WTS:基于Web的Terminal控制台
  13. 交通锥,又称锥形路标、锥形筒、红帽子、方尖碑,是一种道路交通隔离警戒设施。
  14. 前端网页打印插件print.js
  15. c语言定义未知长度一维数组,c++ 如何定义未知元素个数的数组
  16. Introduce Python to data sience/Python 在数据科学中的应用
  17. 布朗大学计算机专业怎么样,数学差的人不配学计算机?布朗大学教授告诉你一毛钱关系都没有...
  18. koa +ts 搭建简单项目
  19. python 理论基础知识试题_Python理论基础知识复习
  20. 计算机网络信息安全管理办法,计算机网络信息安全管理实施细则.doc

热门文章

  1. PCB拼板和工艺边教程
  2. 自己写了一个Asp.net探针的源码,希望大家讨论一下
  3. 计算机内存智能清理系统好些,电脑内存怎么清理?
  4. 软件缺陷的定义和判定标准
  5. MTK 驱动----不开机问题快速分析
  6. 有插件有技巧,Sketchup牛人必备!
  7. 2020东京奥运会奖牌排行--数据可视化
  8. CSS入门教程——字体
  9. 下载好python后,怎么打开,python怎么进入编程界面
  10. python 3.10 添加环境变量的方法