Question

I read the code of redis, it define a struct:

typedef struct zskiplistNode {
    robj *obj;
    double score;
    struct zskiplistNode *backward;
    struct zskiplistLevel {
        struct zskiplistNode *forward;
        unsigned int span;
    } level[];
} zskiplistNode;

and it create node like this:

zskiplistNode *zn = zmalloc(sizeof(*zn)+level*sizeof(struct zskiplistLevel));

Is that mean, if the address of zn is 0x10000, then &(zn->level[0]) is 0x10000+sizeof(zskiplistNode), the memory address of array is behind the struct ?

Was it helpful?

Solution

zn->level (a flexible array member) has some fixed offset w.r.t. zn: if zn is at address 0x10000, then zn->level[0] could be at address 0x10018 because the pointer robj would occupy one 8byte word (assuming a 64 bits x86 machine) and the double score would occupy another 8 byte word -and should be word aligned- and the pointer backward would occupy another word. So zn->level is offset by 3 words, i.e. 24 bytes (i.e. 0x18 in hex).

BTW, the compiler or ABI could insert gaps in your structure (for alignment or ABI compliance). In your particular example it probably would not (with GCC on Linux/x86-64).

You could be interested by the standard offsetof macro and of course the sizeof "operator".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top