sizeof与结构体内存对齐

最近在研究结构体大小的计算,总结如下:

注:如无特殊说明,均是在64位PC的环境下进行实验,以8字节进行对齐,红色字体表示补齐的位数

 根据以下条件进行计算:
      1. 结构体的大小等于结构体内最大成员的整数倍;
      2. 结构体内的成员的首地址相对于结构体首地址的偏移量是对其类型大小的整数倍,比如double型成员相对于结构体的首地址的地址偏移量应该是8的整数倍;
     3. 为了满足规则1和2编译器会在结构体成员之后 进行字节填充

首先是单个结构体的情况。
例1:
struct fish {
const char
* name;//sizeof( const char*) = 8
const char* species;
int teeth; //sizeof(int) = 4
int age;
};
//sizeof( struct fish) = 8+8+4+4 = 24

 如果是结构嵌套结构的情况,依次计算每个成员的大小,遵循上述原则进行对齐,然后相加。
例2:
     struct preferences {
                const char* food;
                float exercise_hours; //sizeof(float) = 4
     };          //大小为 8+4
+4 = 16
struct fish {
const char *name;     //把这句改为 const char name[20];  结果为20 +4 +8+4+4+(8+4+4) = 56
const char* species;
int teeth;
int age;
struct preferences care;
};          //大小为 8+8+4+4+(8+4 +4 ) = 40
例3:
struct meal {
const char* ingredients;
float weight;
};  //大小为 8+4+4 = 16
struct preferences {
struct meal food;
float exercise_hours;
};  //大小为 16+4+4= 24
struct fish {
const char* name;  //把这句改为const char name[20]; 结果为20+4+8+4+4+((8+4+4)+4+4) = 64
const char* species;
int teeth;
int age;
struct preferences care;
};    //大小为 8+8+4+4+((8+4+4)+4+4) = 48
例4:
struct exercise {
const char* description;
float duration;
};
struct meal {
const char* ingredients;
float weight;
};
struct preferences {
struct meal food;
struct exercise exercise;
}; //大小为(8+4
+4)+(8+4+4) = 32
struct fish {
const char* name;//把这句改为const char name[20]; 结果为20+4+8+4+4+((8+4+4)+(8+4+4))= 72
const char* species;
int teeth;
int age;
struct preferences care;
}; //大小为8+8+4+4+((8+4
+4)+(8+4+4)) = 56
发现规律了吧?计算结构体大小时,结构体的第一个成员很重要,要进行相应的补齐,另外,计算结构体的大小还跟结构体中成员的顺序有关,再来看一个例子:
例5:
struct example1{
 
 char c;//sizeof(char) = 1
 
 double d;//sizeof(double) = 8
 
 long l;//sizeof(long) = 4
};// 大小为1+7+8+4+4 = 24
struct example2{
 
char c;
   
long l;
 
double d;
};// 大小为1+4+3+8 = 16
 同样的结构体,成员换了顺序,大小就不同了。所以要遵循内存对齐的规则就OK。
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值