转:struct 关于sizeof的大小-内存对齐问题

 

缺省的对齐方式。

在结构中,编译器为结构的每个成员按其自然对界(alignment)条件分配空间;各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。在缺省情况下,C编译器为每一个变量或是数据单元按其自然对界条件分配空间。

例如,下面的结构各成员空间分配情况。

struct test {
char x1;
short x2;
float x3;
char x4;
};
结构的第一个成员x1,其偏移地址为0,占据了第1个字节。第二个成员x2为short类型,其起始地址必须2字节对界,因此,编译器在x2和x1之间 填充了一个空字节。结构的第三个成员x3和第四个成员x4恰好落在其自然对界地址上,在它们前面不需要额外的填充字节。在test结构中,成员x3要求4 字节对界,是该结构所有成员中要求的最大对界单元,因而test结构的自然对界条件为4字节,编译器在成员x4后面填充了3个空字节。整个结构所占据空间 为12字节。

字节对齐的细节和编译器实现相关,但一般而言,满足三个准则:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。

注意的是:

基 本类型是指前面提到的像char、short、int、float、double这样的内置数据类型,这里所说的”数据宽度”就是指其sizeof的大 小。由于结构体的成员可以是复合类型,比如另外一个结构体,所以在寻找最宽基本类型成员时,应当包括复合类型成员的子成员,而不是把复合成员看成是一个整 体。但在确定复合类型成员的偏移位置时则是将复合类型作为整体看待。

更改C编译器的缺省分配策略
一般地,可以通过下面的方法改变缺省的对界条件:
? 使用伪指令#pragma pack ([n])
#pragma pack ([n])伪指令允许你选择编译器为数据分配空间所采取的对界策略。
例如,在使用了#pragma pack (1)伪指令后,test结构各成员的空间分配情况就是按照一个字节对齐了,格式如下:
#pragma pack(push) //保存对齐状态
#pragma pack(1)
//定义你的结构
//…………
#pragma pack(pop)

附:c中各基本类型的字节数

类型名称
字节数
其它称呼
值的范围
int*(4)signed,
signed int
根据操作系统而定
unsigned int*(4)unsigned根据操作系统而定
__int81char,
signed char
-128 to 127
__int162short,
short int,
signed short int
-32,768 to 32,767
__int324signed,
signed int
-2,147,483,648 to 2,147,483,647
__int648none-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
char1signed char-128 to 127
unsigned char1none0 to 255
short2short int,
signed short int
-32,768 to 32,767
unsigned short2unsigned short int0 to 65,535
long4long int,
signed long int
-2,147,483,648 to 2,147,483,647
unsigned long4unsigned long int0 to 4,294,967,295
enum*none与int相同
float4none3.4E +/- 38 (7 digits)
double8none1.7E +/- 308 (15 digits)
long double10none1.2E +/- 4932 (19 digits)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值