您的位置:首页 > 其它

数据的字节对齐(data structure alignment)

2011-06-20 23:10 344 查看
1.1.1 为什么需要字节对齐
1、处理器的差异

有的处理器,不容许在字节未对齐的地址上访问字或者是多个字的数据。比如sun sparc cpu,不容许在奇数字节上访问一个字,否则会出现异常。

2、出于CPU读取内存数据效率的考虑。

CPU访问内存的时候,都是以字为单位的,如果要读取的数据不在字节对齐的位置上,就要对一次读取数据的操作。比如,在下面的内存模式中,如果要读取0x0000C004处一个字的数据,那么只需要读取一次。如果要读取0x0000C009处一个字的数据,那么需要两次读取,0x0000C009~0x0000C00B一次,0x0000C00C一次。

Address

Byte0

Byte1

Byte2

Byte3

0x0000C000

0x0000C004

01

02

03

04

0x0000C008

11

22

33

0x0000C00C

44

0x0000C010

1.1.1 数据字节对齐讨论

我们在32位x86机器上,以c语言的struct结构为例,讨论字节对齐问题。

C语言中,基本数据类型默认的对齐方式:

类型

长度(字节)

对齐方式

Char

1

1字节对齐

short

2

2字节对齐

int

4

4字节对齐

long

4

4字节对齐

Float

4

4字节对齐

double

8

8字节对齐(windows);4字节对齐(linux)

指针

4

4字节对齐

结构对齐的基本原则:

1、结构体对齐的字节数是此结构体所有成员对齐的字节数中的最大值。

2、结构体每一个成员自身要保持字节对齐。

3、如果结构体中包含嵌套子结构体,那么子结构体自身必须对齐。

4、对于整个结构体,要根据规则1中“结构体对齐的字节数”满足字节对齐,对于没有对齐的情况,需要在最后增加pading。

举例说明:

示例一:

//因为成员d1是double类型,8字节对齐,并且是所有成员中最大的,所以align_sub_test_1也是8字节对齐,根据原则1
struct align_sub_test_1
{
double d1;
char c1;
char pading[7];//为了保证此结构体字节对齐,所以需要填充7个空位,根据原则4
};

//因为成员sub0是8字节对齐,并且是所有成员中最大的,所以align_test_1也是8字节对齐,根据原则1
struct align_test_1
{
struct align_sub_test_1 sub0;
char c;
char array[2];
char pading[1];//为了保证成员i能够字节对齐,所以需要填充1个空位,根据原则2
short i;
char pading[2];//为了保证整个结构体8字节对齐,所以需要填充2个空位,根据原则4
};

测试如下:
size_t l = sizeof(struct align_test_1);//l的值是

struct align_test_1 a1;
a1.sub0.d1 = 1;
a1.sub0.c1 = 3;
a1.i = 7;
a1.c = 5;
a1在内存中的表示为:
00 00 00 00 00 00 f0 3f 03 cc cc cc cc cc cc cc 05 cc cc cc 07 00 cc cc

示例二:
//因为成员i是short类型,2字节对齐,并且是所有成员中最大的,所以align_sub_test_2也是2字节对齐,根据原则1
struct align_sub_test_2
{
short i;
char array[2];
char c;
char pading[1];//为了保证此结构体字节对齐,所以需要填充1个空位,根据原则4
};
//因为成员d1是double类型,8字节对齐,并且是所有成员中最大的,所以align_test_2也是8字节对齐,根据原则1
struct align_test_2
{
struct align_sub_test_2 sub1;
short s1;
short s2;
char pading[6];//为了保证成员d1能够8字节对齐,所以需要填充6个空位,根据原则2
double d1;
};

测试如下:
size_t l2 = sizeof(struct align_test_2);//l2的值是24
struct align_test_2 a2;

a2.sub1.i = 1;
a2.sub1.c = 3;
a2.s1 = 5;
a2.s2 = 7;
a2.d1 = 9;
a2在内存中的表示为:
01 00 cc cc 03 cc 05 00 07 00 cc cc cc cc cc cc 00 00 00 00 00 00 22 40

示例三:
//因为成员i是int类型,4字节对齐,并且是所有成员中最大的,所以align_sub_test_3也是4字节对齐,根据原则1
struct align_sub_test_3
{
int i;
char c;
char pading[3];//为了保证此结构体字节对齐,所以需要填充3个空位,根据原则4
};
//因为成员sub2是align_sub_test_3类型,8字节对齐,并且是所有成员中最大的,所以align_test_3也是8字节对齐,根据原则1
struct align_test_3
{
struct align_sub_test_3 sub2;
char c1;
char pading[1];//为了保证成员s1能够2字节对齐,所以需要填充1个空位,根据原则2
short s1;
char c2;
char pading[3];//为了保证此结构体8字节对齐,所以需要填充3个空位,根据原则4
};

测试如下:

size_t l3 = sizeof(struct align_test_3);//l3的值是16
struct align_test_3 a3;
a3.sub2.i = 1;
a3.sub2.c = 3;
a3.c1 = 5;
a3.s1 = 7;
a3.c2 = 9;
a3在内存中的表示为:

01 00 00 00 03 cc cc cc 05 cc 07 00 09 cc cc cc

参考:http://en.wikipedia.org/wiki/Data_structure_alignment
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: