No.2ベストアンサー
- 回答日時:
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]);
自分だったら、一つ一つ書いているとどうしてもミスするので、この構造体の確保と解放のための関数くらいは書くかもしれません。
No.4
- 回答日時:
>上記のような構造体がある場合、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言語ではありません。
ゴミだろうが何だろうが何らかの値は必ず入ってますので。
No.3
- 回答日時:
>sTestのメンバのsTest01をNULL初期化する方法
NULLで初期化したいのでしょうか?
0で初期化したいのでしょうか?
NULLと0とは意味が異なります。
>sTest01に値が入っていないか(初期化されているか)を判定する方法
値が入っていないかどうかを判定することは、できないのではないかと思います。
というのは、仮に0で初期化した場合、
0という値が「入っている」のであって、「何も値が入っていない」ことにはならないからです。
0という値が入っているかどうかを判定することならば、できます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
- C言語・C++・C# プログラムが書けません。 4 2023/01/22 22:57
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- MySQL my_itemsテーブルのIDにAUTO_INCREMENT を追加ができるかで 1 2023/01/03 09:09
- C言語・C++・C# プログラミングを教えて欲しいです。 配列aは、int a[9]={7,6,12,8,3,5,10,9 4 2022/12/19 23:27
- C言語・C++・C# このプログラミングの問題を教えて欲しいです。 キーボードから整数kを入力し、kが配列aの中に何個存在 2 2022/12/19 22:50
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- PHP $_SESSIONについて教えて下さい。 2 2023/03/02 09:18
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語のポインタに直接アドレス...
-
セグメントエラー
-
fopne で失敗する原因
-
c言語で任意のファイルから読み...
-
C言語でのconstを返す関数
-
【なぜポインタを使うのか】
-
main(int argc,char **argv[])...
-
nullポインタを逆参照とは?
-
構造体を値で渡す良い点はあり...
-
【C言語】戻り値が構造体の関数
-
関数ポインタの高速化のメリット
-
自作strcat
-
アプリを32bitから64bit移行
-
popenした子プロセスのプロセス...
-
C言語によるメモリ読み書き
-
JavaとC++はどう似てる?
-
ハンドル、アドレス、ポインタ...
-
c言語のポインタについて初心者...
-
キャストについて str = (CStr...
-
リトルエンディアンというもの...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
セグメントエラー
-
C言語のポインタに直接アドレス...
-
fopne で失敗する原因
-
init関数の意味
-
Run-Time Check Failure #3とい...
-
戻り値で構造体を返すことは可...
-
LPSTR型の初期化について
-
Cで作成したDLL関数をVBから呼...
-
ExcelVBAでのkernel32(64bit)
-
アプリを32bitから64bit移行
-
構造体とfscanf
-
c言語で任意のファイルから読み...
-
デバイスハンドルとは?
-
main(int argc,char **argv[])...
-
基本アルゴリズムの『返す』の...
-
コンストラクタでnewを失敗した...
-
C言語の関数と配列に関する質問
-
参照型で受け取った引数をポイ...
-
ハンドル、アドレス、ポインタ...
-
DLL<->VB間での受け渡し(文字...
おすすめ情報