【学习笔记】内存对齐

来源:互联网 发布:索引超出数组界限 编辑:程序博客网 时间:2024/06/09 16:59

初始化:

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!




0 0
原创粉丝点击