您的位置:首页 > 其它

【学习笔记】内存对齐

2015-05-19 08:57 323 查看
初始化:

struct student{ 

 int num ; 

 char *name ; 

 int grade ;

};

int main(void)



 struct s arr[]={ 

  { 1 , "chenxi" , 100 } , //方式1:按顺序

{ .name = "chenxi" , .num = 1 , .grade = 100 } ,// 方式2:成员名字前加个 .

 }; 

int i = 0; 

for(i=0 ; i<2; ++i)

{

printf("student's name is %s,num is %d ,grade is %d", arr[i].name , arr[i].num , arr[i].grade);



return 0;

}

使用初始化方式2可以不用对结构的内存分布作假设,一般在使用别人结构体的时候应以这种方式初始化。

结构体内存对齐:

sturct test{ 

 char a ; 

 int b ;

 };

struct test orange ;

结构体必须先实例一个对象才占内存空间 。

结构体中的成员,每一个成员的地址必须是该成员类型大小的整数倍。


结构体中的成员,只能从偏移量为其大小的倍数的地址开始存放。


结构体共占用的内存空间,是其成员中的基础类型的最大值的倍数。

sizeof(orange) = 8 ; char占第一个字节,int只能从偏移量为4的倍数开始存放,char后3个字节被“浪费”,所以这个结构体占8个字节。

枚举类enum 默认占4个字节(int),即使不实例一个对象也占 。

指针大小 = (系统位数 / 8 )个字节 ;

结构体大小的计算方法和步骤(转自:http://blog.csdn.net/kingskyleader/article/details/7926996)
1)将结构体内所有数据成员的长度值相加,记为sum_a; 
2)将各数据成员为了内存对齐,按各自对齐模数而填充的字节数累加到和sum_a上,记为sum_b。对齐模数是#pragma pack指定的数值以及该数据成员自身长度中数值较小者,该数据相对起始位置应该是对齐模式的整数倍。
3)将和sum_b向结构体模数对齐,该模数是【#pragma pack指定的数值】(未指定#pragma
pack时,系统默认的对齐模数(32位系统为4字节,64位为8字节))和【结构体内部最大的基本数据类型成员】长度中数值较小者。结构体的长度应该是该模数的整数倍。

结构体中的位段:

struct test{

          int a:8  ;

          char b ;

          int c  ;

};

struct  test  apple ;

sizeof(apple) = 8   。

因为 a 中使用了前8位 , 还有 24位可以使用 , b 只占8位 , 所以在 a 剩余的空间中放入b 。

struct test{

        int a:9;

        char b  ;

        int  c:8 ;

};

struct test banana  ;

sizeof(banana)大小为4字节,一个int有32位,三个成员一共占用了25个位。

struct test{

 int a:9 ;

  char b ;

 int  c:9 ;

};

struct test juice ;

sizeof(juice) 的大小为 8 字节, a占了前9位 ,b占了16-24位 ,剩余8位不足以存放c ,所以再申请了4个字节存放c。

struct test{

      int a:8 ;

      char b ;

      char c ;

      int  d:7

};

struct test melon 

sizeof(melon) 大小为4字节 。

struct packed_struct

{

    unsigned int f1 :1;

    unsigned int f2 :1;

    unsigned int f3 :1;

    unsigned int type :4;

    unsigned int index :7;

};

表示:标志 f1, f2, f3 分别只需要 1 位。变量 type 只需要 4 位, 而变量index只需要7位,总共14位,不超过2个字节。

sizeof(struct packd_struct)为4,奇怪,为什么不是2或3而是4呢?


其实,哪怕是struct foo {unsigned int f1 :1},也会占用4个字节呢,与unsigned int相同。


总结一下:当位段出现在结构定义中时, 至少会占用等同于unsigned int类型的空间,当所有的位段之和超出,分配另一个unsigned int空间。

另外:unsigned char或者其他类型不必考虑。
 
三.何时位段会失效

例如:

struct bits

{

    unsigned int f1:1;

    int     word;

    unsigned int f3:1;

};

按照内存对齐的规则,位段声明会无效,上述sizeof(struct bits)为12!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: