sizeof与结构体内存对齐

来源:互联网 发布:网络直播的意义 编辑:程序博客网 时间:2024/05/19 03:41

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

注:如无特殊说明,均是在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。
    

0 0
原创粉丝点击