構造体のサイズ取得方法

[戻る]
Who 2002/10/16(水) 19:04:15
下記構造体のサイズは26byteになりますが、

 struct XXX {
     short   aaa ;
     double  bbb ;
     double  ccc ;
     double  ddd ;
 } ;

この構造体のサイズをsizeof関数で取得した場合、
32byteとなってしまいます。

こういった構造体の正確なサイズを取得する方法を教えてください。

Windows2000、VC++6.0、MFC不使用

アイススケーター 2002/10/16(水) 19:35:14
これは、アライメントが8バイトになっているからです。
8バイトの整数倍となります。

プロジェクトの設定でC/C++を選択し、カテゴリをコード生成に
設定し、構造体メンバのアライメントを1バイトに設定してください。

TAD [E-Mail] 2002/10/16(水) 19:41:53
以下のようにすると、特定の構造体だけを変更できます。

#pragma pack(1) // 1バイト境界に設定

struct XXX {
     short   aaa ;
     double  bbb ;
     double  ccc ;
     double  ddd ;
} ;

#pragma pack() // アライメンとをデフォルトに戻す

Who 2002/10/16(水) 19:51:43
[[解決]]
ありがとうございます。

やってみます。

kazuma 2002/10/17(木) 00:10:49
> 下記構造体のサイズは26byteになりますが、

この考え方が間違っています。単純に各メンバのサイズの和になるとは限りません。

> この構造体のサイズをsizeof関数で取得した場合、
> 32byteとなってしまいます。

sizeofで取得したサイズが正しいサイズです。

納得できないという場合は、
「構造体」「パディング」などをキーワ−ドに検索してみてください。
例えば、以下のページの、「Q 【構造体のサイズ】」「Q 【構造体の比較】」
に説明があります。
http://www.st.rim.or.jp/~phinloda/cqa/cqa11.html
http://www.st.rim.or.jp/~phinloda/index.html

普通は、無理にアライメントを調整する必要は有りません。

アイススケーター 2002/10/17(木) 06:03:17
>普通は、無理にアライメントを調整する必要は有りません。

 通信のプログラムでは、ヘッダ部とデータ部に分けて構造体を記述しますが、
この場合、アライメントを調整しないととんでもない結果になります。
 こういった場合があるため、構造体の中に構造体を置く場合はアライメント
に注意する必要があります。
 また、注意したくない場合は、TADさんのようにpragmaを利用しておいたほ
うが、プログラムを移植する場合に後で問題が発生しないでしょう。

 アライメントの調整は、なぜ8バイトがデフォルトかというと、CPUの実行
速度の問題があるからです。
 例えば、データバスが64ビット(8バイト)の場合は、8バイト単位にデータ
が並んでいれば、読込み速度が速いのですが、アライメント調整をしていると、
データがまたがっている場合は1回余分に読み書きが発生してしまいます。
 だから、構造体を8バイト単位で作っておけばデータサイズが大きいけれど
実行速度が上がる場合もあります。

2002/10/18(金) 03:27:24
アイススケーターさん 初めまして

> アライメントの調整は、なぜ8バイトがデフォルトかというと、CPUの実行
>速度の問題があるからです。
> 例えば、データバスが64ビット(8バイト)の場合は、8バイト単位にデータ
>が並んでいれば、読込み速度が速いのですが、アライメント調整をしていると、
>データがまたがっている場合は1回余分に読み書きが発生してしまいます。
> だから、構造体を8バイト単位で作っておけばデータサイズが大きいけれど
>実行速度が上がる場合もあります。
は、説明が簡単すぎて却って判り辛いのではないでしょうか?
i386 から Pentium4 までのプロセッサーの場合内部バスも外部バスも32ビット
だと多くの人は理解していると思います(プロテクトモードの場合ですが)。
インテルのチップでは Itanium が64ビットマシンだと理解しているでしょう。
つまり、セレロンやペンティアム3/4のユーザーは自分の機械のことではないと
感じるのではないだろうかということです(アスロンやデュロンも忘れていませんよ)
以下、間違っていたら笑ってやってください

i386 から Pentium4 までで、浮動小数点で倍精度の時、8バイトアラインメント
が有利な場合があるのだと私は理解しています
そして少しでもベンチマークが有利になるようにデフォルトの設定を8バイト
アラインメントにしたのだと理解しています

アイススケーター 2002/10/18(金) 07:57:00
島さん 初めまして

ソフト系の人にあまり細かい話をしても、話が長くなるため、割愛していました。

ちなみに↓は

>i386 から Pentium4 までのプロセッサーの場合内部バスも外部バスも32ビット
>だと多くの人は理解していると思います(プロテクトモードの場合ですが)。

Pentiumから外部バスは64ビットになっています。
下記、HPを参照下さい。

http://www2.tba.t-com.ne.jp/mv.com/Cpuintel.htm

2002/10/18(金) 09:45:08
うーん、(ひょっとしたら私の読み方が悪いだけなのかもしれませんが...)
>>i386 から Pentium4 までのプロセッサーの場合内部バスも外部バスも32ビット
>>だと多くの人は理解していると思います(プロテクトモードの場合ですが)。
>
>Pentiumから外部バスは64ビットになっています。
>下記、HPを参照下さい。

「私は」ではなく「多くの人は」と表現したのは、私がそう理解して
いるという意味ではなくて、そう受取っている人が多いと思っていると
言いたかったのでしたが、上手く伝えられなかったようです(<ここまで少し愚痴)

pentium から外部バスは64ビットだとの事ですが2Wayインターリーブ
で、内部キャッシュとの転送速度を稼ぐためであって、このことが8バイト
アラインメントの方が有利なことの説明にはならないかと思いますけど。

古いスレッドには追加発言できません。