参考:
https://qiita.com/HImaJin_Tw/items/d5f01e647b74abee4ae4
https://kumikomiya.com/data-structure-alignment/
アライメント
アライメントを知るためには、例となるコードが必要なので以下のコードを提示しときます。
というかこれを実行すれば大体わかるんですけどね。
#include <iostream>
class A
{
public:
char a;
char b;
int c;
};
class B
{
public:
char a;
int b;
char c;
};
int main()
{
A a = A();
B b = B();
std::cout << sizeof(a) << "\t" << sizeof(b) << std::endl;
return 0;
}
これを実行した結果は「8 12」と出力されます。
この違いが起きる原因は、クラス内のメンバ変数の順番によるものです。
ここからは一般的?なバイト数で話します。
まず、char型は1バイトで、int型は4バイトです。
で、このバイト数って、良い意味で言えばメモリアドレスがそのバイト数で割り切れる位置にいることを保証してくれるというものなんですよね。(一概には言えない、今回は説明のためそういうことにする。)
なので、上記でクラスAとクラスBを生成したときに、Aのint cとBのint bは4で割り切れるメモリアドレスの位置にいさせたがるんですよね。
分かりやすく図にするとこんな感じです。補足ですが、合ってるか自信ないです。
突然来たパディング。パディングについては後で軽く説明します。
まぁそれは置いといて、
4バイトのところを4で割り切れるメモリアドレスにするために、パディングを置く関係で無駄な部分が増えてしまい、sizeofで調べると違いが出てしまうんですよね。
じゃあ、int char charという順番で作れば最適解なのかなと思いやってみたら「8」という結果が出ました。正直「6」が出ると思ってました。
class C
{
public:
int a;
char b;
char c;
};
そのくせ、char char charでやれば、「3」と出ました。これは予想してた通り。でも、「4」と出る可能性も考えてた。
class D
{
public:
char a;
char b;
char c;
};
なんでなんでしょうね。環境依存なのか、クラスCでは int が入っていたため全体を4で割り切れる数値にしようとしたためなのか。
でも、Bのような書き方はしない方がいいんだろうなと感じました。
パディング
パディングはゼロパディングとも呼ばれるらしく、要は0を埋めとくだけのことです。悪く言えば数合わせとか場埋めとかそういう話。
いいコンパイラなら1バイトだけを生成するときにそこを利用してくれるかもしれないね。知らんけど。
※没画像