C言語の本にこうありました。
バイナリファイルに対してのメモリの内容をそのまま読み書きするときは、構造体のメンバの並びや境界調整に気をつける
おそらく、境界調整による詰め物を考慮せよということなのかな?
直感的に詰め物がない構造体の方が良いと思われます。
間違っていたらご指摘をお願いします。
というわけで、実際に作ってみました。
C
1struct test { 2 char tt; 3 int hj; 4 char gh; 5 char bn; 6 //double nn; 7 };
offsetof()によって各メンバ変数を確認しました。
char tt : 4byte
int hj : 4byte
char gh : 1byte
char bn : 3byte
☆double 型のコメントを外すと、
char tt : 4byte
int hj : 4byte
char gh : 1byte
char bn : 7byte
double nn : 8byte
規則性がよくわからないのですが・・・
double型なしの時は、gh+bnで4btyeとし、4の倍数として、境界調整されている感じです。
double型ありの時は、gh+bnで8byte, tt+hjで8byteなので、8の倍数で境界調整が行われている・・・のかな・・・
メンバ変数の宣言の順番によっても詰め物のバイト数が変わると予想しているのですが、
#これを、詰め物がない理想的な構造体にするには、どうすれば良いのでしょうか??
メンバ変数の中で最も大きな変数に境界調整は合わせられるという理解で正しいでしょうか??
構造体を作るときにいちいちoffsetofマクロでアライメントを確認するのが、非常に大変な作業なので、構造体を作るときにメンバ宣言のルールのようなものがありましたら、教えてください。
一応windows 64bitで実験しました。
[追記]
Linux 64 bit でもっとメンバ変数を多くして実験してみたところ、
double, float, int, short, unsigned char, char
の順に下から大きい順に並べて構造体を作成してみたところ、gccコンパイラでのoffsetofの結果は、詰め物バイト数を最小にすることができました。
大きいバイト数から数えて(下から)、最大のバイト数の倍数(この場合、double型の8の倍数)になるように構造体の各メンバ変数を作成、調整をしていけば良さそうです。
どうしても、詰め物を入れざるを得ない状況(メンバ変数の全バイトが倍数にならない)で、詰め物を0byteにするのは実質、不可能なんでしょうか?
例えば、詰め物を0byteに出来るように、あえて使わないメンバ変数を作成し、0で初期化した場合、それをバイナリファイルへの出力としたら、中間に余計な0が入ってしまいます。
これでは、ダミー変数を用意しても詰め物と同じ結果になりませんか?
[追記2]
いろいろ出てきますが、詰め物の最小化とメンバ変数の順序には関係性がありそうです。
maismakunさんやケイロニアンさんの回答をもとにすると、CPUとメモリ、メモリと記憶装置、の両方とも理想的な構造体を作成するのは、難しいと思われます
64bit CPUに話を絞るのですが、8^2なので、実行単位は8byteだと思います。
構造体全体のサイズを8の倍数にし、さらに詰め物を最小にするような構造体の作成はやや大変だと思います。
メンバ変数の順序以外に理想形に近づける方法は他にありますでしょうか?

バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/05/09 08:02
2017/05/09 09:36
2017/05/09 09:42
2017/05/09 09:58 編集
2017/05/09 10:11
2017/05/09 10:19
2017/05/09 10:41
2017/05/09 10:49
2017/05/09 10:51
2017/05/09 11:04
2017/05/09 11:19
2017/05/10 01:06
2017/05/11 07:40 編集
2017/05/11 12:15