结构体对齐

C程序结构体对齐

关于结构体对齐我把我的理解写下来;
结构体对齐的步骤:

1,结构体各个成员对齐;
2,结构体圆整

首先要了解几个概念:
1, 指定对齐值: 指定对齐值是由宏#pragma pack (N)指定的值,里面的N必须是2的幂次方,如1,2,4,8,16等。如果没有通过#pragma pack宏那么在32位的Linux主机上默认指定对齐值为4,64位的Linux主机上默认指定对齐值为8,ARM CPU默认指定对齐值为8;
在计算机内存中,结构体变量的存储通常是按字长对齐的。
例:
32位系统中,变量就按照4字节对齐;
64位系统中,变量就按照8字节对齐;

4字节对齐和8字节对齐分别指的是他们的系统的默认对齐值;

2,
int , char , short,在计算机的内存存储中分别占4字节 ,1字节 , 2字节;
它所占内存大小的值叫自身对齐值,就是结构体变量里每个成员的自身大小;

3
有效对齐值: 结构体成员自身对齐时有效对齐值为自身对齐值与指定对齐值中较小的一个,
{自身对齐值,指定对齐值}取较小的一个

4
结构体圆整时,为所有成员中自身对齐值最大的与指定对齐值较小的一个的整数倍
{所有成员中自身对齐值最大的一个,指定对齐值} 取较小的一个

下面我们举一个例子: (32位系统默认对齐值为4)

typedef struct _st_struct1              typedef struct _st_struct2
{                                       {
char a;                                    short  b;
short b;                                   int    c;
int c;                                     char   a;
} st_struct1;                           }st_struct2;
sizeof(st_struct1) = ?                  sizeof(st_struct2) = ? 

结构体的数据类型是相同的,只是顺序有所不同;
<1>左边编译结果是:8
<2>右边编译结果是:12
<1>的结果是这样得出来的:
在这里插入图片描述

结构体成员自身对齐时:
从图中看第一个数据成员放在offset为0的地方,其类型为char,占一个字节。
有效对齐值:b得存储要从自身对齐值与指定对齐值中的较小的一个
min(2,4),取2。short b 就应该从2开始,即它存放在2 . 3内;

int c 的存储也是 min(4,4);取4。 即应该是4 , 5 ,6 ,7;
这样这组结构体数据就存储完成了;

结构体圆整时:在结构体数据成员中自身的对齐值最大的那一个与指定对齐值较小的一个;min(4.4)
所以其整体对齐就是8

<2>的结果是这样得出来的:
在这里插入图片描述

结构体成员自身对齐时:
从图中看第一个数据成员放在offset为0的地方,short b 类型;即存储在0 ,1 的位置
当我们存int c 的时候就应该考虑他的有效对齐值了,自身对齐值与指定对齐值中的较小的一个;
min(4,4) 这样 2, 3的位置就会被空出来。即存储在4 .5 .6. 7 的位置;
接着char a 就存储在8的位置,
在结构体圆整时,其字节数大小为min(4.4),取4。其意思就是虽然 char a 只占一个字节但是需要四个字节存储他,而他只占一个字节,所以结构体总体对齐时为12字节;

宏#pragma pack (N)指定的值
#pragma pack(1):设置结构体的边界对齐为1个字节,其存储时连续的但是处理大数据效率偏低;

#pragma pack(1)                                    #pragma pack(2)
typedef struct _st_struct3                        typedef struct _st_struct4
 {                                                {
 	char 	a;                                       char    a;
	short   b;                                       int     c;
	int     c;                                      short    b
 }st_struct3;                                      }st_struct4;

<3>左边编译结果是:7
<4>右边编译结果是:8
<3>的结果是这样得出来的:
在这里插入图片描述

结构体成员自身对齐时
从图中看第一个数据成员放在offset为0的地方,放 char a.
放置short b 时:
考虑有效对齐值:{自身对齐值,指定对齐值}取较小的一个;
min{2,1} 取 1;所以short b 的存储位置为 1, 2;
放置 int c 时:
有效对齐值:{自身对齐值,指定对齐值}取较小的一个;
min{4,1} 取 1;所以int a 的存储位置 3 ,4 ,5 ,6;
结构体圆整时
{所有成员中自身对齐值最大的一个,指定对齐值} 取较小的一个
min{4,1} 取1 所以结构体总体对齐为7;
<4>的结果是这样得出来的:
在这里插入图片描述

结构体成员自身对齐时
从图中看第一个数据成员放在offset为0的地方,放置char a ;
其位置为0 ;
放置 int c 时:
考虑有效对齐值:{自身对齐值,指定对齐值}取较小的一个;
min{4,2} 取 2;所以int c 的存储位置为 2 ,3 ,4 ,5;
放置 short b时:
考虑有效对齐值:{自身对齐值,指定对齐值}取较小的一个;
min{2,2} 取 2;所以 short b的存储位置为 6, 7;
结构体圆整时
{所有成员中自身对齐值最大的一个,指定对齐值} 取较小的一个
min{4,2} 取2 ;所以结构体总体对齐为8;

**注意:**在我们遇到这样的问题我们应该先弄清楚几个‘ 量 ’ 。什么是自身对齐值,什么是指定对齐值,什么是有效对齐值,什么是结构体圆整;

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值