メモリ上にどのように配置されるのでしょうか。通常意識する必要はありませんが、32bitと64bitで挙動がおかしい場合など、ごく希に調べる必要に迫られる場合があります。そのような場合、各要素のサイズや、構造体先頭からのオフセットを調べることで、メモリ上に構造体がどう置かれるかを調べることができます。C言語でのsizeofやoffsetofに対応する物が、golangのunsafeパッケージに用意されているため、これを利用することで構造体の様子を調べることができます。https://golang.org/pkg/unsafe/今回は以下のようなテスト構造体を使い、メモリ上にどのように置かれるかを調べました。テスト環境はwindows7(32bit)とmac(64bit)になります。[]string}要素のサイズunsafe.Sizeof関数は、引数の要素のサイズを調べ、バイト数をint型で返してくれます。(8)この関数は指定した要素のサイズを返します。そのため、32bit環境ではint64のポインタであるa.ptrは、ポインタのサイズである4byte(=32bit)を返します。24byte)を返し、スライス全体の値は返しません。そのため、要素を追加してもスライス自身の大きさは変化しません。構造体全体の大きさが92byteの偶数になっています。このことから、golangの構造体はパディングされる場合があることがわかります。そのため、要素のサイズを足していったところが、実際にメモリ上に置かれる場所とは限りません。実際にどの位置に配置されているかを確認できます。(112)32bit環境ではa.flagの1byteの後に3byteパディングがされ、a.numが先頭から4byte(=32bit)の位置から始まっています。64bit環境ではa.flagの後ろに7byteパディングされ、a.numが先頭から8byte(=64bit)の位置から始まっています。int32のa.miniも4byteパディングされ、a.strが32byte目から始まるようになっています。このように、32bit環境では32bitに、64bit環境では64bitの倍数から始まるように、コンパイラが構造体にパディングをするようです。以下のように構造体に実態を持つ場合、宣言したとおりに配置されます。そのためAの実態であるaの前後で、構造体のサイズ分だけオフセットが移動しています。構造体Bの中にあるAでも、Bからのオフセットではなく、Aの先頭からのオフセットを出力しています。ポインタとして持つ場合、実態は別のところにあるため、a2のサイズはポインタ分のみになります。構造体を埋め込んだ場合、それらの値がそのままそこに置かれたかのように置かれます。実態として持っているときと違い、構造体Aの要素でもBの先頭からのオフセットを出力しています。ota42yC++/Ruby/RoR/golang/rust/flutter。