2017-07-30 8 views
0

に整列されていないこれは私があることを、この構造体の大きさを期待していた、よく非常に多く、それは私のマシン上で8であることを出てくる私のプログラムサイズはバイト境界

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

int main() { 
    struct bitfield { 
     unsigned a:3; 
     char b; 
     unsigned c:5; 
     int d; 
    }bit; 

    printf("%lu \n",sizeof(bit)); 
    return 0; 
} 

ですunsignedは4バイトであるためです。私がそれ以上のものになることを期待していた理由は、char bがバイト境界にあることが予想され、メモリに正しく配置されるためです。今私の推測では、コンパイラは、これらの4バイトにa、b、cを入れているということです。私はCの新人ですので、私と一緒に抱きしめてください。ビットフィールド以外の他のデータ型は、必ずしも正しくないバイトでなければならないと私は想定していますか?それが正しければ、私は、aは、符号なし整数全体を取ると期待し、bはバイトを取って3バイトのパディングをしています。私はここで何が欠けていますか?

+0

これはおそらくあなたの質問に答えます:[ビットフィールドを持つ構造体のサイズはどのように決定/測定されますか?](https://stackoverflow.com/questions/4129961/how-is-the-size-of-a-struct-with-bit-fields-determined-measured) –

+0

いいえ、それはありません。私は、ビットフィールドサイズがどのように測定されるのか知っています私の質問は、私は文字が間にある場合は、どのように測定されるのですか? – user3491702

+0

簡単に言えば、できるだけビットフィールドから遠く離れないようにしてください。世界に一つの理由がありません。それで、なぜあなたは 'a 'がunsigned int全体と同じ空間を占めると思うのですか?これはビットフィールドです。前後に何が来るのかにかかわらず、3ビットを占めます。 –

答えて

3

私は競合を理解していないようです。

あなたは基本的に持っている:

struct bitfield { 
    unsigned a:3; 
    unsigned padding1:5; 
    char b; 
    unsigned c:5; 
    unsigned padding2:3; 
    unsigned padding3:8; 
    int d; 
}bit; 

aは、3ビット+ 5ビットのパディングを(残りのビットを使用するために、それ以上のビットフィールドが存在しないため)を使用し、バイト1境界上にあります。

bは、バイト2の境界にあり、バイト全体を使用します。

cは、バイト3の境界にあり、5ビット+ 3ビットのパディング(残りのビットを使い切るビットフィールドがもうないため)を使用します。

- int型のパディングがここに来て -

dint境界(マシン上の4バイト)です。パディングには1バイト+データには4バイトを使用します。コメントで@ JonathanLefflerで指摘したように

すべて一緒に、8バイト...

は...ものの、これは実装固有のもので、すべてのコンパイラが同じように動作するという意味ではありません。

+0

Thanks Myst。私が探していた説明だけ。申し訳ありませんが、私はまだ言語の基本です。 – user3491702

+2

コンパイラは許可されていますが、必須ではないので、おそらくこの混乱は起こりますが、必須ではありません(この例では 'unsigned')をそのタイプのものであると定義されたビットフィールドであり、したがって、最初のビットフィールドに4バイト、charに1バイト、4バイト境界に次のビットフィールドを位置合わせするために3バイトのパディング、 2番目のビットフィールドは 'int 'の4バイト、合計16バイトです。これは、すべての実装固有のもので、ビットフィールドとほとんどすべての場合と同様です。 –

+0

@JonathanLeffler私は質問を読んだとき、私の計算によると、それは16バイトでなければならないということです。私はビットフィールドやユニオン、そしてエンディアンをもっと読んでいると思いますが、実装固有のものがどれほどあるかを理解しています。 – user3491702

2

通常、ビットフィールドを1バイトを共有するように並べ替えます。ビットフィールドの間に別の変数を配置すると、使用されていないビットは不要なメモリスペースを使用して終了しますが、スペースは使用します。

コードをいくつかの値でテストし、gdbでプログラムを実行しました。

bit.a = 1; 
bit.b = 'a'; 
bit.c = 4; 
bit.d = 1337; 

GDBにメモリを印刷する場合、出力は、だから我々はそれが唯一の3ビットを使用していますが、最初のバイトが完全に、フィールドaから使用されていることがわかり、この

(gdb) x/8b &bit 
0x7fffffffe118: 00000001 01100001 00000100 00000000 
       00111001 00000101 00000000 00000000 

のように見えます。フィールドbの文字aも1バイトを占有します。

3バイト目(00000100)は、フィールドCの値4と一致します。最後の4バイトの下にあるgdb出力の下限に4バイトを使用する整数がありますが、余分なゼロがありますそこにバイト。これは、最適化された方法でメモリを整列させようとするとき、コンパイラにとって共通の手掛かりです。

関連する問題