- ベストアンサー
構造体の構造体配列初期化
typedef strunct _test01 { int a; int b; } test01_t; typedef strunct _test { int c; test01_t sTest01[256]; } test_t; test_t sTest; 上記のような構造体がある場合、sTestのメンバのsTest01をNULL初期化する 方法とsTest01に値が入っていないか(初期化されているか)を判定する方法を 教えていただけませんか? よろしくお願い致します。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
C言語の場合、グローバル変数として宣言したら0で全部の値が埋められており、ローカル変数として宣言したら、そのときにスタックにあった無意味な値 (いわゆるゴミ) が入っています。 NULL初期化というのが何を意味にしているのかよくわかりませんが、0で埋めるということだったら、bzeroやmemsetを使えばよいと思います。面倒くさいのでtest_tのcの値も0にしますが、こうすると0で埋められるでしょう。 bzero(&sTest; sizeof(sTest)); あるいは、sTest01の値が割り当てられていない状態にするということなら、書き方が違います。C言語はJavaなどと違い、配列には参照ではなく実際の値が入ります。よって、上記のように宣言するとsTest01はtest01_t の大きさ * 256のメモリー領域が自動的に確保されます。 もし、Javaなどのように参照の配列を作りたかったら、ポインタの配列にすることです。 typedef strunct _test { int c; test01_t *sTest01[256]; } test_t; test01_tの後に*が入っていることに注目してください。この場合も、初期化には次のコードでOKです。 bzero(&sTest; sizeof(sTest)); こうすると、sTest01[0]などには(test01_t*)0が設定されていますが、これでポインタの指し先がないことを示せるので。 具体的には、初期化されているか判定するコードはこんな感じです。 if (sTest.sTest01[0] == NULL) { ... } NULLは(void*)0ですが、void*はどのポインタにもなれるというオールマイティな値なので、この比較でOKです。よって、C言語ではmallocやcallocもcastは不要です。 (余談ですが、C++ではキャストがいりますが、そもそもmalloc、callocで普通メモリーを確保しません) この場合、各エントリーの新規割り当ては次のようにして行わなくてはなりません。 sTest.sTest01[0] = malloc(sizeof(test01_t)); また、C言語にはGCが無いので、sTestの値を使わなくなるときに一つ一つfreeしなくてはなりません。これをし忘れると、メモリーリークが起き、プログラムを動かすごとに使えないメモリーが増えていき、仕舞いには、メモリーが確保できなくなってプログラムが異常終了します。 free(sTest.sTest01[i]); 自分だったら、一つ一つ書いているとどうしてもミスするので、この構造体の確保と解放のための関数くらいは書くかもしれません。
その他の回答 (3)
- wormhole
- ベストアンサー率28% (1626/5665)
>上記のような構造体がある場合、sTestのメンバのsTest01をNULL初期化する >方法とsTest01に値が入っていないか(初期化されているか)を判定する方法を >教えていただけませんか? 他の方もいわれてますがNULL初期化とは何をすることをいわれてますか? 「NULLポインタで初期化」であれ「NUL文字で初期化」であれsTest01の初期化にはあいませんが。 もし仮にsTest01を以下のようにポインタの配列とした場合 test01_t *sTest01[256]; sTest01の(NULLポインタでの)初期化を memset(sTest01, 0, sizeof(sTest01)); /* bzero(sTest01, sizeof(sTest01)); と同義 */ のようにするのは厳密にいえばダメです。 C言語の規格上、0はNULLポインタとして扱われますがNULLポインタは0とは限らないので(0でない処理系もあります)。 面倒でも for (int i = 0; i < sizeof(sTest01) / sizeof(sTest01[0]); i++) { sTest01[i] = NULL; } の方がよいです。 変数が初期化されているかされていないかの判定方法はC言語ではありません。 ゴミだろうが何だろうが何らかの値は必ず入ってますので。
- asuncion
- ベストアンサー率33% (2127/6289)
>sTestのメンバのsTest01をNULL初期化する方法 NULLで初期化したいのでしょうか? 0で初期化したいのでしょうか? NULLと0とは意味が異なります。 >sTest01に値が入っていないか(初期化されているか)を判定する方法 値が入っていないかどうかを判定することは、できないのではないかと思います。 というのは、仮に0で初期化した場合、 0という値が「入っている」のであって、「何も値が入っていない」ことにはならないからです。 0という値が入っているかどうかを判定することならば、できます。
- black2005
- ベストアンサー率32% (1968/6046)
Null初期化って何? 値が入っていないこともあり得ない 必ず初期値あるいはゴミが入る