浅析数据对齐

数据对齐

1、为什么需要数据对齐?

最早在8位CPU的时代,是没有数据对齐的需求的。当CPU发展到16位、32位或者64位时代时,才有了数据对齐的需求,因为CPU一次取4个字节的数据(以32位CPU为例),也就是说CPU是这么取数据的:0x00000000 , 0x00000004 , 0x00000008 ,0x0000000C …

如果把 int a = 0x12345678 存储在地址 0x00000000 , 那么CPU只需一次就能取到变量a;

地址
0x000000000x12
0x000000010x34
0x000000020x56
0x000000030x78

如果把 int a = 0x12345678 存储在地址 0x00000003,那么CPU就需要2次才能取到变量a,第一次CPU从0x00000000取到数值0x- - - - - -12,第二次CPU从0x00000004取到数值0x345678- - ,最后CPU把两次取到的值合并成变量a(0x12345678)

地址
0x000000000x–
0x000000010x–
0x000000020x–
0x000000030x12
0x000000040x34
0x000000050x56
0x000000060x78
0x000000070x–

所以从上面的阐述中可以看出,在16位、32位或者64位CPU的时代,数据对齐是有意义的。

注:

1、为什么32位CPU一次取4个字节的数据呢?去研究一下ARM处理器外接的DDR RAM就明白了。

2、这里说的是一次取4个字节的数据,不是说4字节对齐,数据对齐的概念见下文。

3、本文仅通俗的解释数据对齐问题。

2、什么是数据对齐

数据对齐的意思是说:地址值为大小的整数倍。
例如,4字节(字)对齐的合法地址为0x00000000 , 0x00000004 , 0x00000008 , 0x0000000c , 0x00000010 … 0x00001004等;
2字节(半字)对齐的合法地址为0x00000000 , 0x000000002 , 0x00000004 , 0x00000006 … 0x00001002等。
1字节的对齐的合法地址为0x00000000 , 0x000000001 , 0x00000002 , 0x00000003 … 0x00001009等。

自身对齐值(所占字节数)

数据类型自身对齐值
char1
short2
int4
结构体的自身对齐值:其成员中自身对齐值最大的那个值

指定对齐值

数据对齐是C编译器默认的行为,一般C编译器默认4字节对齐,这就是指定对齐值。

有效对齐值

有效对齐值 = min( 自身对齐值,指定对齐值 )

3、实例分析

struct a{
	char a;
	short b;
	char c,d,e;
	short f;	
};

struct b{
	char a;
	char c,d,e;
	short b;
	short f;
	int g;
	char h;
};

// the result is 10  16
printf("%d %d\n",sizeof(struct a) , sizeof(struct b));

struct a

对于struct a的分析(数据在内存中是连续存储的)

char a; 自身对齐值为1,设定对齐值为4,所以有效对齐值为1,所以合法地址为0x00000000
short b; 自身对齐值为2,设定对齐值为4,所以有效对齐值为2,所以合法地址为0x00000002
char c,d,e; 自身对齐值均为1,设定对齐值为4,所以有效对齐值均为1,所以合法地址分别为0x00000004,0x00000005,0x00000006
short g; 自身对齐值为2,设定对齐值为4,所以有效对齐值为2,所以合法地址为0x00000008

结构体的成员变量要对齐排放,结构体本身也要根据自身的有效对齐值圆整(就是结构体成员变量占用总长度需要是对结构体有效对齐值的整 数倍
struct a 中自身对齐值最大为2,所以struct a的打大小就必须是2的整数倍,因为其成员变量的总大小是12,正好是2的倍数,所以sizeof(struct a) 是12。

这里写图片描述

对于struct b的分析(数据在内存中是连续存储的)

char a,c,d,e; 自身对齐值均为1,设定对齐值为4,所以有效对齐值均为1,所以合法地址分别为0x00000000,0x00000001,0x00000002,0x00000003
short b; 自身对齐值为2,设定对齐值为4,所以有效对齐值为2,所以合法地址为0x0000004
short f; 自身对齐值为2,设定对齐值为4,所以有效对齐值为2,所以合法地址为0x00000006
short g; 自身对齐值为2,设定对齐值为4,所以有效对齐值为2,所以合法地址为0x00000008
char h; 自身对齐值为1,设定对齐值为4,所以有效对齐值为1,所以合法地址为0x0000000C

结构体的成员变量要对齐排放,结构体本身也要根据自身的有效对齐值圆整(就是结构体成员变量占用总长度需要是对结构体有效对齐值的整 数倍
struct b 中自身对齐值最大为4,所以struct a的打大小就必须是4的整数倍,因为其成员变量的总大小是14,不是4的倍数,所以struct b的大小要根据其自身有效对齐值(4)圆整,所以sizeof(struct b) 是16。

更多精彩资讯,请扫码关注。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值