我读了redis的代码,它定义了一个struct:
typedef struct zskiplistNode {
robj *obj;
double score;
struct zskiplistNode *backward;
struct zskiplistLevel {
struct zskiplistNode *forward;
unsigned int span;
} level[];
} zskiplistNode;
并创建如下节点:
zskiplistNode *zn = zmalloc(sizeof(*zn)+level*sizeof(struct zskiplistLevel));
这是否意味着,如果zn
的地址是0x10000
,那么&(zn->level[0])
是0x10000+sizeof(zskiplistNode)
,数组的内存地址是否在结构后面?
答案 0 :(得分:1)
zn->level
(一个灵活的数组成员)有一些固定的偏移量w.r.t. zn
:如果zn
位于地址0x10000
,则zn->level[0]
可能位于地址0x10018
,因为指针robj
将占用一个8字节的字(假设64位x86机器)并且双score
将占用另一个8字节字 - 并且应该是字对齐 - 并且指针backward
将占用另一个字。所以zn->level
被3个字偏移,即24个字节(即十六进制为0x18
)。
您可能会对标准offsetof宏感兴趣,当然还有sizeof
“运算符”。