数据对齐

数据对齐是指数据在所在的内存地址必须是该数据长度的整数倍。DWORD数据的内存的起始地址能被4除尽,WORD数据的内存地址能被2除尽。X86CPU能直接访问对其的数据,当它试图访问一个未对齐的数据时,会在内部进行一系列的调整。这些调整对于程序员来说是透明的,但是会降低运行速度,所以编译器在编译程序时会尽量保证数据对齐。

举个例子

int main()

{

char a;

int b;

int c;

}

不同的编译器编译过后,内存中可能出现一下情形(char1字节,int4字节,int4字节)(int4字节 ,char1字节,int4字节),编译器会自动进行数据对其,然后后者占用的内存显然比前者要大。


在结构体中的数据对其原则:

我们看一下原文摘录:

Structure members are stored sequentially in the order in which they are declared: the first member has the lowest memory address and the last member the highest.

Every data object has an alignment-requirement. The alignment-requirement for all data except structures, unions, and arrays is either the size of the object or the current packing size (specified with either /Zp or the pack pragma, whichever is less). For structures, unions, and arrays, the alignment-requirement is the largest alignment-requirement of its members. Every object is allocated an offset so that

offset % alignment-requirement == 0

Adjacent bit fields are packed into the same 1-, 2-, or 4-byte allocation unit if the integral types are the same size and if the next bit field fits into the current allocation unit without crossing the boundary imposed by the common alignment requirements of the bit fields.

每一个数据类型的对象都有各自的对其模数,char为1,short为2,int为4,float为4,double为8.在结构体,联合体和数组中,对齐的模数就是他们的成员里面对齐模数最大的那个。

不同的编译器对齐模数是可以设置的。

在访问内存时,如果地址按4字节对齐,则访问效率会高很多。这种现象的原因在于访问内存的硬件电路。一般情况下,地址总线总是按照对齐后的地址来访问的。如果访问的地址是0x0000 0001开始的4字节内容,系统需要首先访问0x0000 0000,然后读取4个字节的数据,然后再提取三个有用的字节,然后又要去访问0x0000 0004然后又提取4个字节的数据,在提取有用的1个字节才能达到我们的目的。如果一开始就将4个字节的数据对其到0x0000 0000那么我们就可以很轻松的读出4个字节的内容,这也就是数据对齐的意义所在。

结构体对齐参数默认的8字节对齐

举下例子

struct{

short a1;

short a2;

short a3;

}A;

因为a1,a2,a3都是两个字节的,他们最小的模数是2,所以他们占用的内存至少得2的整数倍,那么sizeof(A)是6个字节。

struct{

long a1;

short a2;

}B;

因为a1模数为4,a2模数为2,所以结构体的大小为6,但是他们占用的内存至少要为4的整数倍,所以需要补空字节,增加到8时就符合条件了。


对于位域来说,连续的声明类型大小相同的位域,如果他们申请的宽度加起来不超过他们申明的类型大小,那么他们是可以压缩在一个分配单元中的,对于声明类型大小不同过的位域来说,他们分配在不同的单元中。

struct A{

char a:4;

char b:5;

}

占用的内存空间为2个字节





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值