【C++/C言語】関数から構造体のポインタを返す方法とstaticの重要性

目次

はじめに

C++やC言語で、関数の中で作成した構造体の情報を、呼び出し元のmain関数などで利用したい場合があります。そのようなとき、関数から**構造体を指すポインタを返す(returnする)**という方法があります。

しかし、これには大きな落とし穴があります。通常のローカル変数は、関数が終了すると同時にメモリ上から消滅してしまいます。もし、消滅した変数のアドレスを返してしまうと、呼び出し元はその無効なアドレス(ごみデータ)を指すことになり、深刻なバグの原因となります(これを「ダングリングポインタ」と呼びます)。

この問題を解決するのが static キーワードです。この記事では、static を使って、関数の中から安全に構造体のポインタを返す方法を解説します。


ポインタを返す関数のサンプルコード

このコードは、createDefaultProduct() という関数を定義します。この関数は、内部で staticProduct 型の変数を作成し、そのアドレスを戻り値として返します。

完成コード

#include <iostream>
#include <string>

// 「商品」構造体の定義
struct Product {
    int id;
    std::string name;
};

// --- 1. 関数のプロトタイプ宣言 ---
// 戻り値の型として、Product構造体を指すポインタ(Product*)を指定
Product* createDefaultProduct();

int main() {
    // --- 2. ポインタ型の変数で、関数の戻り値を受け取る ---
    Product* p_item;
    p_item = createDefaultProduct();
    
    // --- 3. 受け取ったポインタ経由でメンバにアクセス ---
    std::cout << "デフォルトの商品情報" << std::endl;
    std::cout << "ID: " << p_item->id << std::endl;
    std::cout << "商品名: " << p_item->name << std::endl;
    
    return 0;
}

// --- 関数の本体(定義) ---
Product* createDefaultProduct() {
    // --- 4. staticを付けて、ローカル変数を宣言 ---
    static Product defaultItem;
    
    defaultItem.id = 999;
    defaultItem.name = "標準品";
    
    // --- 5. 作成した変数のアドレス(&)を返す ---
    return &defaultItem;
}

コードの解説

1. Product* createDefaultProduct()

関数の戻り値の型を Product* と定義しています。これは、「この関数は、Product 型の構造体を指す**ポインタ(アドレス)**を返します」という意味です。

2. p_item = createDefaultProduct();

main関数側では、Product* 型のポインタ変数 p_item を用意して、createDefaultProduct 関数が返したアドレス値を受け取っています。

3. static Product defaultItem;

これが、このテクニックの最も重要なポイントです。

  • 通常のローカル変数: 関数が終了すると、メモリから消滅します。
  • static を付けたローカル変数: プログラムが終了するまで、メモリ上に存在し続けます。関数の外からでも、そのアドレスは有効なままです。

static を付けずに Product defaultItem; とした場合、関数が終了した瞬間に defaultItem は消滅し、返されたアドレスは無効になります。その無効なアドレスにアクセスしようとすると、プログラムは未定義の動作(クラッシュなど)を引き起こします。

4. return &defaultItem;

static で宣言した変数 defaultItem のアドレスを、アドレス演算子 & で取得し、関数の戻り値として返しています。


まとめ

今回は、関数から構造体のポインタを安全に返す方法を解説しました。

  • 関数の戻り値の型を、ポインタ型(例: struct_name*)として宣言する。
  • 関数の中で返す構造体変数は、static キーワードを付けて宣言し、関数終了後もメモリに残り続けるようにする。
  • 関数の戻り値として、その static 変数のアドレス&variable)を返す。

関数からポインタを返す方法は、動的メモリ確保 (new) を使う方法もありますが、static ローカル変数を使うのは、関数が常に同じ単一のインスタンスを返せばよい場合に使える、よりシンプルな手法です。

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

この記事を書いた人

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

目次