记录一下结构体的数据类型大小怎么算,主要看对齐数和地址偏移量

计算原理

举个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<iostream>
typedef struct student {
int num;
char name[10];//8 byte
int com, math, english;
double average;//8 byte
} stu;
stu boy[1000], * p;
int main() {
std::cout << sizeof(stu)<<"\n";
std::cout << sizeof(int);
return 0;
}

对齐数的大小,在vs编译器里,是数据类型大小和默认对齐数(vs是8)的最小值。

从第二个数据开始,数据首个字节的地址的偏移量要为对齐数的整数倍

对于数据类型stu,num先填充4 bytes,之后第二个char name[10]的对齐数是10和8的较小值,为8 bytes,首地址应为8的整数倍的偏移地址量,最小为8,所以从8开始存放name,

第三个数据还是int,现在已经填充了num,4个0xcc,name,加起来偏移地址为18,int对齐数是4,再填充两个0xcc,从偏移地址20开始填充三个int,20+12=32,

第四个数据是double,对齐数是其64位的大小,8bytes,32是8的整数倍,可以直接填入,加起来是40,所以sizeof(stu) 的大小是40

430208b28b1148d99a4e0b1d209590c4

数组的情况是同理的,把他看成几个连续的单个数据算就好了

当结构体中有其他结构体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>
typedef struct student {
int num;
char name[10];//8 byte
int com, math, english;
double average;//8 byte
} stu;
typedef struct cls {
int class_number;
stu one;
};
stu boy[1000], * p;
int main() {
std::cout << sizeof(stu)<<"\n";
std::cout << sizeof(cls);
return 0;
}

stu one 需要从其结构体内部数据的最大对齐数的整数倍的地址偏移量开始,这里内部最大是8,所以应该从cls里的地址偏移量为8开始存储,就是40+8=48。