0

我阅读了redis的代码,它定义了一个结构:

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));

这是否意味着,如果地址zn0x10000,那么&(zn->level[0])0x10000+sizeof(zskiplistNode),数组的内存地址在结构后面?

4

1 回答 1

1

zn->level(一个灵活的数组成员)有一些固定的偏移量 wrt zn:如果zn在 address 0x10000,那么zn->level[0]可能在 address0x10018因为指针robj将占用一个 8 字节字(假设是 64 位 x86 机器)并且双精度score将占用另一个 8 字节字 - 并且应该字对齐 - 指针backward将占用另一个字。因此zn->level偏移 3 个字,即 24 个字节(即0x18十六进制)。

顺便说一句,编译器或 ABI 可能会在您的结构中插入间隙(用于对齐或 ABI 合规性)。在您的特定示例中,它可能不会(在 Linux/x86-64 上使用 GCC)。

您可能会对标准的offsetof宏感兴趣,当然还有sizeof“运算符”。

于 2013-05-08T07:12:09.247 回答