内存对齐规则和实战

这篇文章是我的平时的一个笔记修改后来的。这里主要介绍一下内存对齐的规则,以及提供一些实战一下。几篇我觉得比较好的详细的介绍内存对齐的作用什么的博文会在文末附上。

规则

在开始实战前,需要了解下规则。

首先了解变量的有效对齐值N

  • 数据类型对齐值自身的对齐值:也就是基本数据类型的自身对齐值 如int 为4字节, char为1字节

  • 指定对齐值:#pragma pack (value),这个宏中的value就是指定对齐值

  • 结构体或类的自身对齐值:MAX(其成员变量自身对齐值)

  • 数据成员、结构体和类的有效对齐值:MIN(自身对齐值,指定对齐值)

规则一

每个成员的起始地址应满足 “起始地址%N == 0”

规则二

结构体的有效对齐值要圆整(就是结构体成员变量占用的总长度需要是对结构体 有效对齐值 的整数倍)

<font color="blue>"总长度 % 有效对其值 == 0


实战

示例

先看一个例子运用一下规则,热热身。

可以先分析下,成员变量的有效对齐值是什么,然后要满足规则一和规则二,变量的存储地址要后移多少,最后算出的结构图的总长度是多少。(这里没有#pragma pack())

struct A
{
int a;
char b;
short c;
};

示例分析

  1. 首先确定每个成员的有效对齐值 因为没有指定对齐值 所以为自身数据类型的对齐值
  a--4字节  b--1字节  c--2字节
  1. 起始地址必须满足规则一“起始地址%N = 0”
    令起始地址位0x0000  按照变量的顺序存储<br>
变量a的起始地址 0x0000%4 = 0;满足条件 占用4个字节 0x0000--0x0003 占四个字节变量
b 的起始地址 是 0x0004%1 = 0满足条件 占用一个字节 就是0x0004
变量c 的起始地址 是 0x0005%2 !=0 所以起始地址要向后移位 直到满足条件位置 0x0006%2 = 0
满足条件 占用2字节 0x0006-- 0x0007
所以结构体总共占用了8字节
  1. 根据结构体的有效对齐值圆整
  	结构体的有效对齐值是 其成员中自身对齐值最大的那个值为4
由于8字节正好是4的整数倍 所有就是8字节

实战开始

上面分析了一次,下面可以进行实战了。下面加上了#pragma pack(),所以需要注意这里的有效对齐值是什么了,回顾前面MIN(自身对齐值,指定对齐值)。

实战1
#pragma pack(4)//指定对齐值
struct B
{
char b;
int a;
short c;
}; union C
{
int a[5];
char b;
double c;
}; struct D
{
int n;
C a;
char c[10];
};
实战2
#pragma pack(8)//指定对齐值
struct example1
{
short a;
long b; }; struct example2
{
char c;
example1 struct1;
short e;
};

简单分析在下划线下面


内存单元从0开始编号

实战1分析
#pragma pack(4)//指定对齐值
struct B //10 + 2(圆整) = 12
{
char b;//[0]
int a;//[1]...[4]...[7]([1]...[4]表示地址后移到单元[4])
short c;//[8]...[9]
}; union C //20字节 联合体按成员所占最长单元算
{
int a[5];
char b;
double c;
}; struct D // 34+2(圆整) = 36
{
int n; // [0]...[3] (4个字节)
C a; // [4]...[23] (20字节)
char c[10]; // [24]...[33] (10字节)
};
实战2分析

#pragma pack(8)
struct example1//8
{
short a;//[0]...[1]
long b;//[2]...[4]...[7]
}; struct example2//14+2(圆整)=16
{
char c;//[0]
example1 struct1;// [1]...[4]...[11]
short e;//[12]...[13]
};

悄悄附上我的测试代码运行的截图


嗯 写了一些,还是以理解规则然后实战为主,附上详细的他人的博文,参考参考。

博文

最新文章

  1. typeof(self) 的作用
  2. win7如何让局域网其他电脑通过IP直接访问自己电脑的网站
  3. Java数组一定要初始化才能使用吗?
  4. jquery基础总结
  5. 各种&quot;居中&quot;
  6. junit浅学笔记
  7. Android SDK 环境变量配置(Windows)
  8. python---------函数练习题
  9. AngularJS 框架
  10. PHP之工厂方法模式(三)
  11. UVA - 11468:Substring
  12. 轻松搞定RocketMQ入门
  13. [译]ABP vNext介绍
  14. get skill
  15. 我的DIY作品
  16. maven 项目 查询部分关心的字段
  17. 12.16daily_scrum
  18. Linux命令记录----chkconfig命令
  19. .Net EF Core数据库使用SQL server 2008 R2分页报错How to avoid the “Incorrect syntax near &#39;OFFSET&#39;. Invalid usage of the option NEXT in the FETCH statement.”
  20. Java8 Map的遍历方式

热门文章

  1. Java数据结构之TreeMap
  2. 记一次排查mysql数据库连接未关闭问题的过程
  3. HTML基础知识自学教程
  4. 在VM虚拟机Windows Server r2上部署安装Microsoft Dynamics CRM 2016 步骤详解(一)
  5. 【AMAD】django-activity-stream
  6. mysql数据库设置密码
  7. vue点击编辑按钮,内容变成input可以修改,也可以删除
  8. superset采集流程
  9. ARM 版本 瀚高 数据库的启动命令
  10. Netty的那些”锁”事