構造体のサイズ取得方法 – プログラミング – Home

構造体のサイズ取得方法
 
通知
すべてクリア

[解決済] 構造体のサイズ取得方法


Who
 Who
(@Who)
ゲスト
結合: 23年前
投稿: 8
Topic starter  

下記構造体のサイズは26byteになりますが、

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

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

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

Windows2000、VC++6.0、MFC不使用


引用未解決
トピックタグ
アイススケーター
 アイススケーター
(@アイススケーター)
ゲスト
結合: 23年前
投稿: 280
 

これは、アライメントが8バイトになっているからです。
8バイトの整数倍となります。

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


返信引用
TAD
 TAD
(@TAD)
ゲスト
結合: 23年前
投稿: 54
 

以下のようにすると、特定の構造体だけを変更できます。

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

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

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


返信引用
Who
 Who
(@Who)
ゲスト
結合: 23年前
投稿: 8
Topic starter  

ありがとうございます。

やってみます。


返信引用
kazuma
 kazuma
(@kazuma)
ゲスト
結合: 24年前
投稿: 217
 

> 下記構造体のサイズは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

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


返信引用
アイススケーター
 アイススケーター
(@アイススケーター)
ゲスト
結合: 23年前
投稿: 280
 

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

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

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


返信引用
島
 島
(@島)
ゲスト
結合: 23年前
投稿: 238
 

アイススケーターさん 初めまして

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

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


返信引用
アイススケーター
 アイススケーター
(@アイススケーター)
ゲスト
結合: 23年前
投稿: 280
 

島さん 初めまして

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

ちなみに↓は

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

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

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


返信引用
島
 島
(@島)
ゲスト
結合: 23年前
投稿: 238
 

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

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

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


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました