/*********************************************************************
* Author : Samson
* Date : 09/20/2013
* Test platform:
* #1 SMP Debian 3.7.2-0+kali8
* gcc (Debian 4.7.2-5) 4.7.2
* *******************************************************************/
先看看从网上的查找到的关于:编译器是按照什么样的原则进行对齐的?
先让我们看四个重要的基本概念:
1.数据类型自身的对齐值:
对于char型数据,其自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4单位字节。
2.结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。
3.指定对齐值:#pragma pack (value)时的指定对齐值value。
4.数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中小的那个值。
typedef struct Double
{
char c;
double b;
int f;
short a;
char e;
}DOUBLEAREA;
以上结构体,有人认为长度是24,理由是在double b前必须按照double的长度进行补齐前面的char c,所以在double b前的长度就应该是8个字节了。因为为8+8+4+4=24;而按照以上的四条原则中的第一条:int,float,double类型,其自身对齐值为4单位字节,那么应该为:4+8+4+4=20;
根据第一条规则,个人理解的意思是对于每一种类型的结构体中的变量,前面的结构体字段的长度总和必须是当前类型的自身对齐的整数倍,就上面的这个结构体的定义:对于此结构体应用此规则的应用如下:
typedef struct Double
{
char c;
double b; //前面的c的空间必须是double的对齐字节单位对齐,所以前面的要补齐到4个字节
int f;
short a;//而此short类型的前面所占空间(补课后的空间)只要是short的对齐单位2字节对齐即可;前面的字段的补齐后的已经是4的倍数了
char e; //此char类型的前面的所占空间(补齐后的空间)只要是char的对齐单位1字节的整数倍即可
}DOUBLEAREA;
那么就以上的结构体,还有没有能够进行优化的空间呢?
根据以上的分析,已经看到把占用对齐字节越大的放在结构体前的话,会在空间上更加优化,因为越大的空间的值在结构体的后面的话,对齐的单位更大,浪费的空间也就更大了,那么我们把上面的结构体修改一下,就能够节省4个字节了,如下:
typedef struct Double
{
double b;
int f;
short a;
char c;
char e;
}DOUBLEAREA;
修改后的空间占用为:8+4+2+1+1=16
为了节省空间修改结构体的原则为:
1)按对齐单位的大小从大到小的顺序进行定义;
2)把对齐单位相同的写在一块;
测试代码及结果:
#include <stdio.h>
#include <stdlib.h>
typedef struct Double
{
char c;
double b;
int f;
short a;
char e;
}DOUBLEAREA;
typedef struct DoubleNew
{
double b;
int f;
short a;
char c;
char e;
}DOUBLEAREANEW;
int main()
{
int lenDouble, lenDoubleNew;
DOUBLEAREA DoubleArea;
DOUBLEAREANEW DoubleAreaN;
lenDouble = sizeof(DoubleArea);
lenDoubleNew = sizeof(DoubleAreaN);
printf("DoubleArea len is %d DoubleAreaN len is %d
", lenDouble, lenDoubleNew);
return 0;
}
root@quieter:/usr/local/samsonfile/yygytest# ./a.out
DoubleArea len is 20 DoubleAreaN len is 16
后续又有对存在 位域字段的结构体的长度的计算及优化空间的日志,地址如下: