3
int main()
{

    struct a
    {
        struct a *next;
        struct a *prev;
    };

    struct a *A[2];

    printf("Address of (&(A[0])->next) = %p",(&(A[0])->next));
    getch();
    return 0;
}

上記のprintfステートメントでは、「struct a」構造の「次の」ポインターにアクセスしています。開発コンパイラーでプログラムを実行すると、有効なメモリーアドレスが得られます(まだメモリーを割り当てていません)。これがどのように起こるかの説明は非常に役に立ちます。

「next」および「prev」フィールドにメモリが割り当てられていますか?

4

2 に答える 2

4
&(A[0])->next

配列next内の最初の構造体のメンバーのアドレスです。A

これは と考えられ&A[0] + offsetof(struct a, next)ます。つまり、これは、初期化されていないポインターの値に、構造体のベースアドレスからA[0]のメンバーのオフセットを加えたものnextになります (構造体の最初の要素であるため、たまたまゼロになりますnext)。

C 標準によると、プログラムは無効なポインターでポインター演算を実行するため、未定義の動作を呼び出します。ただし、実際には、これはほとんどの場合、クラッシュして偽のアドレスを出力することはありません (加算が実行されるだけで、ポインターの背後のメモリには何もアクセスしません)。ただし、実際にポインターを逆参照すると、クラッシュが発生することが予想されます。

于 2013-06-05T11:50:39.080 に答える