“:” 用法
以下摘自 redis
的 serve.h
#define LRU_BITS 24
typedef struct redisObject {
unsigned type:4;
unsigned encoding:4;
unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
* LFU data (least significant 8 bits frequency
* and most significant 16 bits access time). */
int refcount;
void *ptr;
} robj;
结构体中的冒号后的数字表示该字段占的位数。
4 + 4 + 24 + 32 + 64 = 128 4 + 4 + 24 + 32 + 64 = 128 4+4+24+32+64=128,所以该结构体占 16 字节(还要符合下述对齐规则,显然该结构体是对齐的)
对齐规则
规则一:每个字段的起始地址都是该字段大小的整数倍
typedef struct {
char a; // 1 个字节
int b; // 4 个字节
double c; // 8 个字节
} A;
按照规则一对齐后可得排列 a... bbbb cccc cccc
,所以是 16 个字节。
.
表示填充,一个a
表示字段 a 的一个字节,四个字节一组方便数数。
规则二:整个结构体大小该是结构体最大字段的整数倍
如果改变结构体顺序。
typedef struct {
char a; // 1 个字节
double c; // 8 个字节
int b; // 4 个字节
} A;
- 先按照规则一:此时排列将是
a... .... cccc cccc bbbb
,也就是 20 字节 - 在按照规则二:结构体最大字段大小为 8 个字节,所以要填充到 24 字节,最终排列是
a... .... cccc cccc bbbb ....
优化空间
根据上述例子可知,相同字段的结构体,排列顺序不同,对齐后所占空间也不同。
那没有没有一种通法,能使得结构体所占空间最小?有,按照字段大小降序排列。
优化前
typedef struct {
char* a; // 8 个字节
short b; // 2 个字节
double c; // 8 个字节
char d; // 1 个字节
float e; // 4 个字节
char f; // 1 个字节
long g; // 8 个字节
int h; // 4 个字节
} A;
- 先按照规则一:
aaaa aaaa bb.. .... cccc cccc d... eeee f... .... gggg gggg hhhh
,共 52 字节 - 在按照规则二:
aaaa aaaa bb.. .... cccc cccc d... eeee f... .... gggg gggg hhhh ....
,共 56 字节
优化后
typedef struct {
char *a; // 8 个字节
double c; // 8 个字节
long g; // 8 个字节
float e; // 4 个字节
int h; // 4 个字节
short b; // 2 个字节
char d; // 1 个字节
char f; // 1 个字节
} A;
- 先按照规则一:
aaaa aaaa cccc cccc gggg gggg eeee hhhh bbdf
,共 36 字节 - 再按照规则二:
aaaa aaaa cccc cccc gggg gggg eeee hhhh bbdf ....
,共 40 字节