2009-12-03 5 views
35

可能性の重複:サイズ

#include <stdio.h>  

struct employee 
{ 
    int id; 
    char name[30]; 
}; 

int main() 
{ 
    struct employee e1;  
    printf("%d %d %d", sizeof(e1.id), sizeof(e1.name), sizeof(e1)); 
    return(0); 
} 

出力である:


Why isn’t sizeof for a struct equal to the sum of sizeof of each member?

は、以下のCコードを検討

構造体のサイズが個々のコンポーネント変数のサイズの合計と等しくないのはなぜですか?

+1

gccでpacked属性を使用することができます。これにより、パディングが削除され、構造ができるだけ小さく保たれます。 struct test_t { int c; } __attribute __((__ packed__)); – eaanon01

+0

(少なくとも)の重複http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member – dmckee

+6

eaanon01 。本当に本当に良い理由があり、すべての意味が理解されていない限り、誰かに、属性がパックされたものと同じように移植不可能なものを伝えるべきではありません。 –

答えて

52

コンパイラは、配置要件のためにパディングを追加することがあります。これは、構造体のフィールド間のパディングに適用されるだけでなく、構造体の終わりにも適用されることがあります(構造体の配列には、各要素が適切に揃うようになります)。例えば

struct foo_t { 
    int x; 
    char c; 
}; 

cフィールドは、パディングを必要としないにもかかわらず、構造体は、一般にsizeof(struct foo_t) == 8(32ビットシステム上で有することになる - 32ビットintタイプではなく、システムを)cフィールドの後に3バイトのパディングが必要になるためです。

(x86やCortex M3などの)システムでは埋め込みは必要ないかもしれませんが、パフォーマンス上の理由からコンパイラがそれを追加することがあります。だから、基本的に、あなたの構造に34バイトを持っており、次の構造体がアドレスに配置する必要があり、それは4

にアドレスを複数に揃えるされているため、6バイトに整列

+1

+1、ただし6バイトに整列するのは奇妙です。おそらく私は低レベルのものでは少し遅れているでしょう。 –

+1

さて、名前はオフセット4から始まり(34)、34まで伸びています.34は4の倍数ではないので、36に終わりです。これは9 * 4です。私には理にかなっています! –

+2

32ビット境界(4,8,16,24,32,36、...)への整列 – Mordachai

0

は、奇妙ではない、それはへの複数あります4. 34の後の最も近い値は36である。このパディング領域は構造のサイズに数えられる。

2

前述したように、Cコンパイラはアラインメント要件のためにパディングを追加します。これらの要件は、しばしばメモリサブシステムと関連しています。いくつかのタイプのコンピュータは、4バイトのようないくつかの「nice」値まで並べられたメモリにのみアクセスできます。これはしばしば単語の長さと同じです。したがって、Cコンパイラは構造体のフィールドをこの値に整列させて、より簡単にアクセスできるようにすることができます(たとえば、4バイトの値は4バイト境界に合わせる必要があります)。 。私は他の理由もあると信じています。詳細はthisウィキペディアのページをご覧ください。

1

デフォルトの配置はおそらく4バイトです。 30バイト要素が32になったか、構造全体が次の4バイト間隔に切り上げられました。