忍者ブログ

神戸電子専門学校ゲームソフト学科の生徒が運営するGESのブログです。

   

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

やばかった・・・

どうもたくあんっす。
ながらく更新できなくて申し訳ないっす!

ここ数日なかなか自由な時間がなかったんだ。
仕事と家事の両立は大変ですね。普通にやってる他の人がすげぇわ・・・
まぁ楽しいので辛くはないんですけどね。

んじゃ今日はいつもC#では面白くないかなと思ったのであまり学校でやらないと思う話を。

拍手[0回]


皆さんは「アライメント」と言う言葉は知っていますか?
グーグル先生によると意味は並べるとか比較と言う意味らしいです。

さて何故この言葉を書いたかと言うとあるモノに非常に関係があるからです。

それは・・・・・・構造体です!

えっ今さら構造体かよ、なんて思っているあなた、構造体とクラスは全く同じモノだと思ってませんか?
びみょーに違います。詳しくはMSDNのサイトとかよんで下さい。違いが書いてます。

まぁC++では構造体とクラスはほぼ同意なのでC++やってる方は
あんまり使わないなかもしれませんが。

C#だと構造体は値型、クラスは参照型をしっかり頭に置いとかないと大変な時があります。

そんなこんなで拡張する予定がない小さいデータ集合なんかは構造体で、その逆はクラスでメモリ管理とかを考えると中々使う事もあるようですよ。

まぁ今日はそんな事言いたいんじゃないんだ。
そうアライメントですよ!アライメント!


それでは次の質問です。
この構造体は何バイトでしょうか?
とりあえずC言語で記述しました。

struct     sample
{
       int       l_test;
       char   c_test;
}

わからない人は実際にsizeofで出して見て下さい面白い結果がでます。

さてwindowsの環境にもよるので各自sizeofでまず、各型のサイズを計測してみて下さい。
私は int型は4バイト、char型は1バイトとなりました。
それでは構造体のサイズは・・・・
4+1=5のはずです。
どうでしょうか?

結果はなんと・・・8バイト!?

どういうことでしょうか?
これが構造体のアライメントです。

実はこれは構造体に型の異なるメンバを宣言した場合、
そのメンバの一番大きなメンバの型のサイズに合わせて、メモリに配置していまうんです。

つまりさっきの構造体で一番大きな構造体のメンバはintですので4バイトとなり、それに合わせてcharに余分な3バイトが付加されてしまいます。(この余分をパディングと言う)
誤解されると困るので書いときますが必ずしもメンバのサイズ=アライメントとは限りません。その辺はもっと詳しいサイトとかもあるのでしらべて下さい。

と大げさに書きましたが特に困らないですよね?そうですね。
アライメントは一つの言語のみしか使わない場合には大して問題でないです。

ですが、例えばバイナリファイルに書き出して別のOSで読み込む場合や別の言語で作成したDLLを読み込む場合、ネットワークで通信する時、変なアライメントがあるとデータを正しく読み込めなかったり、例外が起きて最悪アプリケーションが落ちるなんて事があります。


勿論、解決方法はいくらでもあるので、そこまで神経質になる事はないですがそういうモノがあるとだけ知ってもらえれば充分です。

実は私もC++で作成されたDLLをC#で読み込むのに、構造体のアライメントで苦労しました。
上記の例は簡単ですが、これが構造体の中に構造体が入れ子で大量にあったり、共用対の中に多次元配列があったりと、どんどん複雑になり、大変でしたw
まぁC++/CLIとかを使えば割と簡単にラッパークラスを作れるようですが・・・・・

今回はアライメント!
これだけ覚えておいて下さい。
いつか役に立つ時もあるでしょう。


以上!!
次回はC#でなんかやります。
PR

COMMENT

NAME
TITLE
MAIL(非公開)
URL
EMOJI
Vodafone絵文字 i-mode絵文字 Ezweb絵文字
COMMENT
PASS(コメント編集に必須です)
SECRET
管理人のみ閲覧できます

無題

  • by 2年
  • 2011/10/22(Sat)13:13
  • Edit
C++のbool型はsizeofは1バイトを返す
クラス内にひとつだけbool型変数がありアライメントによって
無駄に+3パディングされるなら
効率面だけを考えるならwin32で定義されているBOOL型(int)の
方がいいのだろうか?

無題

  • by たくあん
  • 2011/10/22(Sat)23:08
  • Edit
ふむ、win32の論理型サイズはプラットフォームに依存するので、アライメントを考えるのであれば使用するべきでない。

誤解があるかも知れないから言っておきますが、パディングが入るのはマシンがメンバを読み取るときとかにわかりやすくするために行っているものです。
私もこの辺は勉強不足ですが、効率云々より、結局環境依存のBOOLを使うとDLLなどをインポートする際にアライメントの問題になる。

それからパディングですが、属性と言う物を設定してアライメントを指定したり構造体の合計サイズを指定する事も可能なので、可能な限りプラットフォームに依存しないboolを使用して下さい。

そしてBOOLはどうしてもそれを使用しなければならない時だけ使って下さい。

あと基本BOOLは4バイト(環境による)でboolは1バイト。
なので普通にフラグとして使うなら無駄ですしね。
ですが、昔はboolは4バイトだったりしますので実際に動かす実機(CPU)、コンパイラ毎に確認するのが大事です。

まぁ長々書きましたが、制作等ではあんまり気にする事もないですから、深く考えないでも大丈夫ですよ。仕事とかではありそうですけどねw

あとこの知識は私が調べてそう理解しているだけなので、せっかく興味をもってくれたなら、どんどん自分で調べて、実験する事を進めますよ!

無題

  • by 2年
  • 2011/10/25(Tue)00:48
  • Edit
なるほど・・・
色々わかりやすい説明ありがとうございます!

ブログ内検索

最新コメント

[01/29 人面犬]
[10/01 8ch]
[09/12 uncle]
[09/10 某卒業生]
[06/07 uncle]

カレンダー

03 2024/04 05
S M T W T F S
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

テスト

Copyright ©  -- GESブログ --  All Rights Reserved
Design by CriCri / Photo by Geralt / powered by NINJA TOOLS / 忍者ブログ / [PR]