Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1021741
  • 博文数量: 297
  • 博客积分: 11721
  • 博客等级: 上将
  • 技术积分: 3431
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-25 10:21
文章分类

全部博文(297)

文章存档

2016年(9)

2011年(71)

2010年(137)

2009年(80)

分类: LINUX

2010-03-15 18:16:55

缺省的对齐方式。

在结构中,编译器为结构的每个成员按其自然对界(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 * signed,
signed int
根据操作系统而定
unsigned int * unsigned 根据操作系统而定
__int8 1 char,
signed char
-128 to 127
__int16 2 short,
short int,
signed short int
-32,768 to 32,767
__int32 4 signed,
signed int
-2,147,483,648 to 2,147,483,647
__int64 8 none -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
char 1 signed char -128 to 127
unsigned char 1 none 0 to 255
short 2 short int,
signed short int
-32,768 to 32,767
unsigned short 2 unsigned short int 0 to 65,535
long 4 long int,
signed long int
-2,147,483,648 to 2,147,483,647
unsigned long 4 unsigned long int 0 to 4,294,967,295
enum * none 与int相同
float 4 none 3.4E +/- 38 (7 digits)
double 8 none 1.7E +/- 308 (15 digits)
long double 10 none 1.2E +/- 4932 (19 digits)

C++的基本类型:

     类型             字节数

  • int              4
  • short int      2
  • long int       4
  • unsigned int  4
  • unsigned short int 2
  • unsigned long int   4
  • char             1
  • unsigned char  1
  • float     4
  • double     8
  • long double  8
  • int * 4
  • int &  4
unin 联合的大小为成员最大成员的大小.


struct test 
{
        char x4;   //1
        char x1[4];//4+1(填充1,为与x2对齐)
        short x2;  //2
};
sizeof(test) = 1+5+2 =8

struct test 
{
        char x4;   //1
        char x1[4];//4
};
sizeof(test)=5

-
阅读(391) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~