结构体中数据的对齐性

原创 2006年06月09日 18:12:00

对齐

        对齐性是一内存地址的特性,表现为内存地址模上 2 。例如,内存地址 0x0001103F 4 3 个地址就叫做与 4n 3 对齐 4 指出了所用的 2 。内存地址的对齐性取决于所选择 2 幂值。同的地址模 8 7

 

       一个内存地址符合表达式 Xn 0 ,那说该地址对齐 X

 

       CPU 行指令就是于内存上的数据行操作,些数据在内存上是以地址为标记的。于地址来独的数据会有其占用内存的字数。如果它的地址对齐于它的字数,那就称作数据自然对齐,否对齐。例如,一个标记 8 的浮点数据的地址对齐 8 ,那么这数据就自然对齐

 

数据对齐性的编译处

       设备编译器以一防止造成数据未对齐的方式来数据行地址分配。

 

       个的数据型,编译其分配的地址是数据型字数的倍数。因此,编译器分配 long 量的地址 4 的倍数,就是 2 制表示地址的,最后两位 0

 

       另外,编译器以一自然对齐每构成的方式来填充构体。参看下面的代里面的构体 struct x_

 

     struct x_

      {

            char a;     // 1 byte

            int b;      // 4 bytes

            short c;    // 2 bytes

            char d;     // 1 byte

      } MyStruct;

 

      编译器填充构以使其自然对齐

 

例如

      下面的代码说明了编译器是如何在内存中填充的。

 

      // Shows the actual memory layout

      struct x_

     {

           char a;            // 1 byte

           char _pad0[3];     // padding to put 'b' on 4-byte boundary

           int b;            // 4 bytes

           short c;          // 2 bytes

           char d;           // 1 byte

           char _pad1[1];    // padding to make sizeof(x_) multiple of 4

     }

 

     在作sizeof(struct x_)运算都会返回12

 

      第二含有两填充成分:

 

             *char _pad0[3]使得int b 4节边界上对齐

 

             *char _pad1[1]使得构数struct _x  bar[3]对齐

             填充使得bar[3]各个量能自然对齐

 

看下面的构:

struct MyStruct

{

double dda1;

char dda;

int type

};

对结MyStruct采用sizeof会出么结果呢?sizeof(MyStruct)多少呢?也你会这样求:

sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13

但是当在VC测试上面构的大小,你会发现sizeof(MyStruct)16。你知道VC中会得出这样一个

VC对变量存的一个特殊理。了提高CPU的存速度,VC一些量的起始地址做了“对齐理。在默情况下,VC定各成员变量存放的起始地址相构的起始地址的偏移量必须为该变量的型所占用的字数的倍数。下面列出常用型的对齐方式(vc6.0,32位系)

对齐方式(量存放的起始地址相构的起始地址的偏移量)

Char

偏移量必须为sizeof(char)1的倍数

int

偏移量必须为sizeof(int)4的倍数

float

偏移量必须为sizeof(float)4的倍数

double

偏移量必须为sizeof(double)8的倍数

Short

偏移量必须为sizeof(short)2的倍数

各成员变量在存放的候根据在构中出序依次申,同按照上面的对齐方式整位置,空缺的字VC会自填充。同VC了确保构的大小为结构的字节边界数(即该结构中占用最大空型所占用的字数)的倍数,所以在最后一个成员变量申后,会根据需要自填充空缺的字

下面用前面的例子来VC到底怎么样来存放构的。

struct MyStruct

{

double dda1;

char dda;

int type

}

上面的构分配空候,VC根据成员变量出序和对齐方式,先第一个成dda1分配空,其起始地址跟构的起始地址相同(好偏移量0sizeof(double)的倍数),员变量占用sizeof(double)=8个字;接下来第二个成dda分配空这时下一个可以分配的地址构的起始地址的偏移量8,是sizeof(char)的倍数,所以把dda存放在偏移量8的地方对齐方式,员变量占用sizeof(char)=1个字;接下来第三个成type分配空这时下一个可以分配的地址构的起始地址的偏移量9,不是sizeof(int)=4的倍数,对齐方式偏移量的问题VC填充3个字三个字没有放什么东西),这时下一个可以分配的地址构的起始地址的偏移量12好是sizeof(int)=4的倍数,所以把type存放在偏移量12的地方,员变量占用sizeof(int)=4个字这时整个构的成员变量已都分配了空的占用的空大小8+1+3+4=16为结构的字节边界数(即构中占用最大空型所占用的字sizeof(double)=8)的倍数,所以没有空缺的字需要填充。所以整个构的大小sizeof(MyStruct)=8+1+3+4=16,其中有3个字VC填充的,没有放任何有意西。

下面再个例子,交一下上面的MyStruct的成员变量的位置,使它成下面的情况:

struct MyStruct

{

char dda;

double dda1;

int type

}

构占用的空间为多大呢?在VC6.0境下,可以得到sizeof(MyStruc)24合上面提到的分配空的一些原,分析下VC么样为上面的构分配空的。(简单说明)

struct MyStruct

{

char dda;//偏移量0对齐方式,dda占用1个字

double dda1;//下一个可用的地址的偏移量1,不是sizeof(double)=8

//的倍数,需要7个字才能使偏移量变为8对齐

//方式),因此VC填充7个字dda1存放在偏移量8

//的地址上,它占用8个字

int type//下一个可用的地址的偏移量16,是sizeof(int)=4的倍

//数,int对齐方式,所以不需要VC填充,type

//放在偏移量16的地址上,它占用4个字

}//所有成员变量都分配了空,空间总的大小1+7+8+4=20,不是

//节边界数(即构中占用最大空型所占用的字sizeof

//(double)=8)的倍数,所以需要填充4个字,以构的大小

//sizeof(double)=8的倍数。

所以该结的大小sizeof(MyStruc)1+7+8+4+4=24。其中的有7+4=11个字VC填充的,没有放任何有意西。

VC对结构的存的特殊理确提高CPU储变量的速度,但是有候也来了一些麻,我也屏蔽掉量默对齐方式,自己可以量的对齐方式。

 

VC中提供了#pragma pack(n)量以n节对齐方式。n节对齐就是说变量存放的起始地址的偏移量有两情况:第一、如果n大于等于该变量所占用的字数,那偏移量必须满足默对齐方式,第二、如果n小于该变量的型所占用的字数,那偏移量n的倍数,不用足默对齐方式。构的大小也有个束条件,分下面两情况:如果n大于所有成员变型所占用的字数,那么结构的大小必须为占用空最大的量占用的空数的倍数;

须为n的倍数。下面明其用法。

#pragma pack(push) //保存对齐

#pragma pack(4)//4节对齐

struct test

{

char m1;

double m4;

int m3;

};

#pragma pack(pop)//复对齐

以上构的大小16,下面分析其存情况,首先m1分配空,其偏移量0足我自己定的对齐方式(4节对齐),m1占用1个字。接着m4分配空这时其偏移量1,需要3个字这样使偏移量n=4的倍数(因sizeof(double)大于n,m4占用8个字。接着m3分配空这时其偏移量124的倍数,m3占用4个字这时经为所有成员变量分配了空,共分配了16个字n的倍数。如果把上面的#pragma pack(4)#pragma pack(16),那可以得到构的大小24。(请读者自己分析)

相关文章推荐

腾讯笔试题—结构体的数据对齐

typedef struct _A{ char a; int b; float c; double d; int *pa; char* pc; short e; }A; #...

彻底搞清计算结构体大小和数据对齐原则

彻底搞清计算结构体大小和数据对齐原则                                          By Qianghaohao                         ...

由sizeof求结构体大小时涉及到的数据对齐

本博文转自http://www.cnblogs.com/dolphin0520/    作者:海子 结构体字节对齐       在用sizeof运算符求算某结构体所占空间时,并不是简单...
  • dby3579
  • dby3579
  • 2016年07月22日 10:44
  • 444

C语言中的结构体数据存储-对齐规则

(1)什么是字节对齐   一个变量占用 n 个字节,则该变量的起始地址必须能够被 n 整除,即: 每个变量的起始存放地址 % n = 0,      对于结构体,这个 n 取其成员种的数据类型...

C++学习之旅——结构体和联合体的区别,以及数据对齐方式影响内存大小

转载于:http://blog.csdn.net/dreamback1987/article/details/8504943 联合体 用途:使几个不同类型的变量共占一段内存(相互覆盖) ...

结构体数据对齐

之前对数据对齐的认识只是片面的,今天看到介绍这个的博客,对数据对齐的了解更加印象深刻了 1 -- 结构体数据成员对齐的意义 许多实际的计算机系统对基本类型数据在内存中存...

C结构体中数据的内存对齐问题【转自hbyh专栏】

最近在写一个服务器,需要使用结构体来格式化缓冲区,所以需要考虑结构体内存对齐的问题,于是,就google到了这篇文章,写得很深入透彻,于是转载到我这里来,纯属学习。1.先看下面的例子:struct A...

基本数据类型变量 结构体 union 类的内存字节对齐

系原创,转载时请帖上地址: 什么叫内存字节对齐:就是在内存地址中按照一个规则(这个规则具体是什么在下面说)把一个变量放在它应该在的内存地址,而不是把变量从前到后一个紧挨着一个存放(那是        ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:结构体中数据的对齐性
举报原因:
原因补充:

(最多只允许输入30个字)