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

のアドレスが の場合、zn配列0x10000のメモリアドレス&(zn->level[0])0x10000+sizeof(zskiplistNode)struct の後ろにあるということですか?

4

1 に答える 1

1

zn->level(柔軟な配列メンバー) にはいくつかの固定オフセット wrtがありますzn:znが address0x10000にある場合、ポインターは 1 つの 8 バイト ワード (64 ビット x86 マシンを想定) を占有し、double は別の 8 バイト ワードを占有するため、 address にあるzn->level[0]可能性があります。単語を揃えると、ポインターは別の単語を占有します。3 ワード、つまり24 バイト (つまり16 進数) のオフセットも同様です。0x10018robjscorebackwardzn->level0x18

ところで、コンパイラまたは ABI は、構造にギャップを挿入する可能性があります (アライメントまたは ABI 準拠のため)。あなたの特定の例では、おそらくそうではありません(Linux / x86-64のGCCを使用)。

標準的なoffsetofマクロと、もちろんsizeof「演算子」に興味があるかもしれません。

于 2013-05-08T07:12:09.247 に答える