C++中的结构体与sizeof

类别:VC语言 点击:0 评论:0 推荐:

  

C++中的结构体与sizeof

 

       前几天在C/C++版上看到一个关于“对齐”和“sizeof”的问题。原来一直以为自己已经把这个问题弄清楚了,但是看了帖子之后才发现仍有许多概念模糊的地方,于是把MSDN翻出来细细看了一下,又做了几个小试验验证自己的想法,并作此文,作为自己对这个问题的一个阶段性小结。文中若有不对之处,望各位大侠批评指正。

 

影响结构体的sizeof的因素:

1)  不同的系统(如32位或16位系统):不同的系统下int等类型的长度是变化  的,如对于16位系统,int的长度(字节)为2,而在32位系统下,int的长度为4;因此如果结构体中有int等类型的成员,在不同的系统中得到的sizeof值是不相同的。

2)   编译器设置中的对齐方式:对齐方式的作用常常会让我们对结构体的sizeof值感到惊讶。

 

对齐

为了能使CPU对变量进行高效快速的访问,变量的起始地址应该具有某些特性,即所谓的“对齐”。例如对于4字节的int类型变量,其起始地址应位于4字节边界上,即起始地址能够被4整除。变量的对齐规则如下(32位系统):

Type

Alignment

char

在字节边界上对齐

short (16-bit)

在双字节边界上对齐

int and long (32-bit)

在4字节边界上对齐

float

在4字节边界上对齐

double

在8字节边界上对齐

structures

单独考虑结构体的个成员,它们在不同的字节边界上对齐。

其中最大的字节边界数就是该结构的字节边界数。

 

MSDN原话:Largest alignment requirement of any member

 

理解结构体的对齐方式有点挠头,如果结构体中有结构体成员,那么这是一个递归的过程。

 

对齐方式影响结构体成员在结构体中的偏移

设编译器设定的最大对齐字节边界数为n,对于结构体中的某一成员item,它相对于结构首地址的实际字节对齐数目X应该满足以下规则:

X  =  min(n, sizeof(item))

例如,对于结构体 struct {char a;  int  b} T;

当位于32位系统,n=8时:

a的偏移为0,

b的偏移为4,中间填充了3个字节, b的X为4;

 

当位于32位系统,n=2时:

a的偏移为0,

b的偏移为2,中间填充了1个字节,b的X为2;

 

结构体的sizeof

设结构体的最后一个成员为LastItem,其相对于结构体首地址的偏移为offset(LastItem),其大小为sizeof(LastItem),结构体的字节对齐数为N,则:

 

结构体的sizeof 为:  若offset(LastItem)+ sizeof(LastItem)能够被N整除,那么就是offset(LastItem)+ sizeof(LastItem),否则,在后面填充,直到能够被N整除。

 

例如:32位系统,n=8,

结构体 struct {char a; char b;} T;

 struct {char a;  int  b;} T1;

 struct {char a;  int  b; char  c;} T2;

 

sizeof(T) == 2;      N = 1   没有填充

sizeof(T) == 8;      N = 4   中间填充了3字节

sizeof(T2)==12;    N = 4   中间,结尾各填充了3字节

 

    注意:

1)  对于空结构体,sizeof == 1;因为必须保证结构体的每一个实例在内存中都有独一无二的地址。

2)  结构体的静态成员不对结构体的大小产生影响,因为静态变量的存储位置与结构体的实例地址无关。例如:

struct {static int I;} T;      struct {char a; static int I;} T1;

sizeof(T) == 1;            sizeof(T1) == 1;

    3) 某些编译器支持扩展指令设置变量或结构的对齐方式,如VC,

详见MSDN(alignment of structures)

 

本文地址:http://com.8s8s.com/it/it1293.htm