C++中的结构体与sizeof

影响结构体的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)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值