new で構造体を割り当てる

new でメモリ上に構造体の領域を割り当てます。

前田稔の超初心者のプログラム入門

プログラムの説明

  1. いよいよ new とポインタの登場です。
    new は Object Class などでよく使われますが、malloc と同様にメモリ領域を割り当てる命令で、 C++ では new および delete 演算子を使って、メモリ領域の動的な確保と開放を行います。
    malloc の詳細は Malloc で領域を確保 を参照して下さい。
    TData *data; は、構造体(TData)の定義ですが、確保されるのは構造体が割り当てられているメモリのアドレス(ポインタ)です。
    TData *data = NULL;
    前回説明したように、次のように書くと構造体そのものがメモリ領域に割り当てられます。
    TData data;
    今回のプログラムでは、実際の構造体の領域は new TData; で割り当てます。
    data = new TData;
    構造体のポインタを通してメモリ領域を参照するときは「->」を使います。
    data->v1 = 30;
    割り当てた領域は delete で開放して下さい。
    delete data;
    if (data) でポインタが格納されていることを確認して開放するのが常套手段になっています。
    C++/CLI の環境では、使われていないメモリ領域を自動的に探し出して開放するガベージ・コレクションの機能が備わっています。
    ガベージ・コレクションは Native Code でも効くのでしょうか。 (?_?;
    /*★ 構造体(struct) のテスト    前田 稔 ★*/
    #include <stdio.h>
    #include <conio.h>
    
    typedef struct
    {   int     v1;
        int     v2;
        int     sum;
    }   TData;
    TData   *data = NULL;
    
    int main(void)
    {
        data = new TData;
        data->v1 = 30;
        data->v2 = 40;
        data->sum = data->v1 + data->v2;
        printf("data->v1= %d,  data->v2= %d,  data->sum= %d\n", data->v1, data->v2, data->sum);
        _getch();
        if (data)   delete data;
        return 0;
    }
    
  2. 次のプログラムを見て下さい。
    構造体そのものは直接メモリ領域に割り当てていますが、sum の計算は func() 関数で行っています。
    func() 関数に渡しているパラメータ &data は、構造体の場所を示すポインタです。
    func() 関数では &data を *data で受け取ります。
    *data はポインタなので「->」で構造体のメンバーを参照します。
    このように構造体をパラメータとして渡すときは、ポインタで渡すのが常套手段になっています。
    /*★ 構造体(struct) のテスト    前田 稔 ★*/
    #include <stdio.h>
    #include <conio.h>
    
    typedef struct
    {   int     v1;
        int     v2;
        int     sum;
    }   TData;
    TData   data;
    
    void  func(TData *data)
    {
        data->sum = data->v1 + data->v2;
    }
    
    int main(void)
    {
        data.v1 = 30;
        data.v2 = 40;
        //data.sum= data.v1 + data.v2;
        func(&data);
        printf("data.v1= %d,  data.v2= %d,  data.sum= %d\n", data.v1, data.v2, data.sum);
        _getch();
        return 0;
    }
    
  3. 構造体をパラメータとして渡すときは、ポインタで渡すのが常套手段になっていると説明しましたが、構造体そのものを渡せない訳ではありません。
    func() 関数に data 構造体を直接渡す書き方です。
    int main(void)
    {
        data.v1 = 30;
        data.v2 = 40;
        func(data);
        printf("data.v1= %d,  data.v2= %d,  data.sum= %d\n", data.v1, data.v2, data.sum);
        _getch();
        return 0;
    }
    
    func() 関数では「*」を付けずに data で受け取ります。
        void  func(TData data)
        {
            data.sum = data.v1 + data.v2;
        }
        
    func() 関数では sum に「data.v1 + data.v2」の値を格納しているつもりなのですが main() で印字すると値が設定されていません。
    実際にプログラムを実行して確認して下さい。
  4. 今回のように呼び出された関数で、パラメータを通じて構造体に値を設定するときはポインタで渡さなければなりません。
    そこでクイズです。 (^_^;)
    計算された値(70)はどこに格納されたのでしょう。 (?_?;
    答えはスタック領域に積み込まれた構造体の sum に格納されています。
    スタック領域は、関数から戻るとすぐに開放されるので「data.sum = data.v1 + data.v2;」は実質的に意味の無いコードです。

超初心者のプログラム入門(C/C++)