struct结构体大小计算
计算结构体大小需要分为两步:
一、确定内存对齐单位
(1)CPU周期
WIN vs qt 默认8字节对齐
Linux 32位 默认4字节对齐,64位默认8字节对齐
(2)结构体最大成员(基本数据类型变量)
(3)预编译指令#pragma pack(n)手动设置 n只能填1 2 4 8
上面三者取最小的,就是实际对齐单位(这里的“实际对齐单位”是我为了方便区分随便取的概念)
二、根据对齐单位进行内存对齐
(1)结构体第一个变量存放在起始地址0处
(2)a. 如果接下来的变量整个大小能放在前一个变量剩余对齐单位里,则在剩余对齐单位里,以当前变量大小为单位划分(例:对齐单位是8,char c; int i; 则c放在地址0x00处,由于对齐单位还剩7个字节,可以放下int变量,则int变量仍放在该行,但在该行以int大小4划分,即 i 放在地址0x04处,0x01-0x03什么也不放);
b. 如果当前变量大小不能放在前一个变量剩余对齐单位里,则以对齐单位对齐,把当前变量另起一个对齐单位,放在对齐单位的整数倍处。
(3)最后是结构体对齐,整个结构体的大小需要是对齐单位的整数倍
示例如下:
(1)
#pragma pack(4)
struct One{
double d; //0x00-0x07
char c; //0x08——补3字节
int i; //0x0C-0x0F
};
sizeof(struct One) = 16
struct Two{
char c; //0x00——补3字节
double d; //0x04-0x0B
int i; //0x0C-0x0F
};
sizeof(struct Two) = 16
(2)
#pragma pack(8)
struct One{
double d; //0x00-0x07
char c; //0x08——补3字节
int i; //0x0C-0x0F
};
sizeof(struct One) = 16
struct Two{
char c; //0x00——补7字节
double d; //0x08-0x0F
int i; //0x10-0x03——补4字节
};
sizeof(struct Two) = 24