【C++/C言語】共用体 (union) の使い方 | 同じメモリ領域を共有する仕組み

目次

はじめに

C++の構造体(struct)は、全てのメンバ変数がそれぞれ個別のメモリ領域を持ちます。一方、「共用体 (union)」は、定義された全てのメンバ変数が、一つの同じメモリ領域を共有(共用)するという、特殊な性質を持っています。

これは、複数のデータ型のうち、常にどれか一つしか使わないことが分かっている場合に、メモリを節約するためのテクニックです。共用体のサイズは、その中で最も大きいメンバ変数のサイズになります。

この記事では、unionの基本的な使い方と、その「メモリ共有」という挙動について、サンプルコードで解説します。


union を使ったサンプルコード

このコードは、ProductCode(商品コード)という共用体を定義します。この共用体は、id(数値コード)とshortName(文字コード)という2つのメンバを持ちますが、どちらか一方しか有効な値として保持できません。

完成コード

#include <iostream>

using namespace std;

// 商品コードを格納する共用体の定義
union ProductCode {
    int id;           // 数値コード
    char shortName[4];  // 3文字の英字コード (+ヌル文字)
};

int main() {
    ProductCode code;
    
    // --- 1. 整数メンバ(id)に値を設定 ---
    cout << "最初に、数値コードとして 999 を設定します。" << endl;
    code.id = 999;
    
    // この時点では両方のメンバが同じメモリを見ている
    cout << "数値コード(id): " << code.id << endl;
    cout << "文字コード(shortName): " << code.shortName << " (※意味のないデータ)" << endl;
    
    cout << "\n--- 2. 文字メンバ(shortName)に値を設定 ---" << endl;
    cout << "次に、文字コードとして 'ABC' を設定します。" << endl;
    code.shortName[0] = 'A';
    code.shortName[1] = 'B';
    code.shortName[2] = 'C';
    code.shortName[3] = '\0'; // 終端ヌル文字
    
    // shortNameに書き込んだことで、idの領域も上書きされた
    cout << "文字コード(shortName): " << code.shortName << endl;
    cout << "数値コード(id): " << code.id << " (※値が破壊された)" << endl;

    return 0;
}

コードの解説

union ProductCode { ... };

union キーワードを使って、ProductCode という共用体を定義しています。int 型の id と、char[4] 型の shortName という2つのメンバを宣言していますが、これらは別々の場所ではなく、同じメモリ領域を異なる解釈で使う、という宣言になります。

メモリの共有

  1. code.id = 999;: id メンバに 999 を代入すると、共用体のメモリ領域に 999 という数値データが書き込まれます。このとき shortName メンバを通じて同じメモリを覗くと、999 のビットパターンを無理やり文字として解釈しようとするため、意味不明なデータが見えます。
  2. code.shortName[0] = 'A'; ...: 次に、shortName メンバに "ABC" という文字データを書き込むと、共用体のメモリ領域は A, B, C, \0 というビットパターンで上書きされます。その結果、元々あった 999 という数値データは破壊され、id メンバを通じて同じメモリを覗くと、"ABC\0" のビットパターンを無理やり数値として解釈した、全く異なる値が見えます。

このように、共用体では、最後に値を書き込んだメンバだけが有効なデータを保持し、それ以外のメンバにアクセスすると、意味のない(破壊された)データを読み込んでしまうことになります。


まとめ

今回は、C++の共用体 union の基本的な仕組みについて解説しました。

  • union は、全てのメンバが同じメモリ領域を共有する。
  • そのため、同時に一つのメンバしか有効な値を保持できない。
  • 複数のデータ型のうち、どれか一つだけを格納する場合のメモリ節約のために使われる。

共用体は、C言語との互換性や、非常に低レベルなメモリ操作など、限定的な場面で使われる特殊な機能です。ほとんどの場合、struct や、C++17で導入された std::variant を使う方が、より安全で分かりやすいプログラムになります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次