
C言語入門|配列・構造体・共用体のメモリ配置とアクセス
ここまで配列やポインタをたくさん使ってきましたが、
「実際にメモリの中でどう並んでいるのか」を
ちゃんと意識したことはありますか?
C言語では、
- 配列
- 構造体
- 共用体
これらは見た目が似ていても、メモリ上の姿はまったく違う存在です。
今回は、1バイト単位のマス目の図を使って、
「どこに、何が、どれだけ置かれているのか」を可視化しながら見ていきます。

まずは配列のメモリ配置から
配列は、C言語の中でもっとも素直なメモリ構造を持っています。
サンプルプログラム(配列)
プロジェクト名:10-5-1 ソースファイル名: sample10-5-1.c
#include <stdio.h>
int main(void)
{
int exp[3] = {10, 20, 30};
printf("exp[0]=%d\n",exp[0]);
printf("exp[1]=%d\n", exp[1]);
printf("exp[2]=%d\n", exp[2]);
return 0;
}実行結果
exp[0]=10
exp[1]=20
exp[2]=30配列のメモリ配置を1バイト単位で見る
ここでは、次の前提で考えます。
- 1マス(セル)=1バイト
- int型=4バイト
- exp[3] は int が3個 → 合計12バイト
配列 scores のメモリ配置例

アドレスと要素の対応
| 要素 | 使用する番地 |
|---|---|
| exp[0] | 1000~1003 |
| exp[1] | 1004~1007 |
| exp[2] | 1008~1011 |
配列は、
同じ型の要素が、隙間なく、順番に並ぶ
という、とても分かりやすい構造をしています。
なぜ [] 演算子で配列にアクセスできるのか
ここで、これまで学んできた「特殊構文」を思い出します。
配列アクセスの正体
- 配列名は、先頭要素のアドレスに変換される。
- [] 演算子は、ただのメモリアクセス
つまり、
exp[0]は、内部的には
*(exp + 0)として評価され、
- scores → 1000番地
- +0 → そのまま
→ 1000番地に int 型変数を生み出す
という流れで処理されています。
構造体のメモリ配置を見てみよう
次は構造体です。
構造体は「連続して確保されることが多い」ですが、
必ずしも隙間なしではありません。
サンプルプログラム(構造体)
プロジェクト名:10-5-2 ソースファイル名: sample10-5-2.c
#include <stdio.h>
struct Status {
short level;
int hp;
};
int main(void)
{
struct Status s = {5, 120};
printf("level=%d, hp=%d\n", s.level, s.hp);
return 0;
}構造体のメモリ配置とパディング
前提
- short型=2バイト
- int型=4バイト
構造体 Status のメモリ配置例

詳細な割り当て
| メンバ | 使用番地 |
|---|---|
| level | 1008~1009 |
| パディング | 1010~1011 |
| hp | 1012~1015 |
なぜ隙間(パディング)ができるのか
これは、
- CPUが高速にアクセスできる位置に
- int型を配置したい
という理由によるものです。
構造体は、
見た目どおりに並ぶとは限らない
という点が重要です。
共用体のメモリ配置はまったく別物
最後に共用体です。
構造体と名前は似ていますが、考え方は正反対です。
サンプルプログラム(共用体)
プロジェクト名:10-5-3 ソースファイル名: sample10-5-3.c
#include <stdio.h>
union Status {
short level;
int hp;
};
int main(void)
{
union Status u;
u.hp = 200;
printf("hp=%d\n", u.hp);
u.level = 3;
printf("level=%d\n", u.level);
return 0;
}共用体のメモリ配置
共用体では、
すべてのメンバが、同じメモリ領域を共有
します。
共用体 Status のメモリ配置例

メンバごとの対応
| メンバ | 使用番地 |
|---|---|
| level | 1008~1009 |
| hp | 1008~1011 |
同じ番地を使うため、
- hp に代入したあと
- level を読むと
意味の違う値として解釈されることになります。
共用体が使われる主な場面
共用体は、同じメモリ領域を複数の型で使い回したいときに使われます。
代表的な用途は次のとおりです。
- メモリ容量が厳しい環境
・組み込み機器やマイコン
・RAM が数 KB〜数十 KB しかない環境
ポイントは
→ 同時に複数のメンバを使わないことが前提、という点です。
現在の共用体の使用状況
結論から言うと、使用頻度はかなり下がっています。
理由は次のとおりです。
- メモリが潤沢になった
- 可読性・安全性が低い
- 型の解釈ミスがバグや未定義動作につながりやすい
そのため現在では、
- 業務アプリケーション
- 一般的なCプログラム
では、構造体や別変数で書く方が主流です。
配列・構造体・共用体の違いまとめ
| 種類 | メモリの使い方 |
|---|---|
| 配列 | 同じ型が順番に並ぶ |
| 構造体 | メンバごとに別領域(隙間あり) |
| 共用体 | 全メンバが同じ領域を共有 |
この違いを理解しておくと、
- ポインタ操作
- 関数引数
- バイナリデータ処理
が一気に読みやすくなります。
