- ベストアンサー
NULL領域を読み書きするの意味が?
C言語の初学者です。 コンパイラは、Borland C++ 5.5.1 for Win32 を使っています。 たまたま見つけた C magazine プログラミングの禁じ手Web版 C言語編で、「NULL領域を読み書きする」という個所があり、下記ソースで発覚すると掲載されていました。 (http://www.cmagazine.jp/src/kinjite/c/null.html#index5) void f() { static char *theTxt; strcpy(theTxt,"TEST\n"); printf("%s",theTxt); } 自分の環境で、下記のソースで動かしてみたところ、アプリケーションエラーになりました。 #include <stdio.h> #include <string.h> int main(void) { static char *theTxt; /* (1) */ strcpy(theTxt,"TEST\n"); printf("%s",theTxt); return 0; } この禁じ手の意味そのものが、全く理解できませんでした。 ・NULL領域というのは、(1)のstatic定義されたポインタことをさしているのか? ・(1)の static をつけないで実行すると、正常終了したので、static の領域に書き込んではいけないのか? (そんなことはないと思うのだが)
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
NULL領域というのは、NULLポインタで示された領域ということかと 思われます。NULLポインタは値としては0をとることが一般的ですが、 定義としては「どこも指さないポインタ」です。 ですから、NULLポインタへのアクセスは、仮に動作したとしても適切な 処理ではなく、行なってはいけません。 http://www.st.rim.or.jp/~phinloda/cqa/cqa3.html 例題ですが、明示的に初期化していないstatic宣言された変数は0(数値型) またはNULL(ポインタ型)に初期化されますので、theTxtはNULLポインタ です。それを strcpy(theTxt,"TEST\n"); でアクセスしていますので 適切な処理ではないということになります。 >NULL領域というのは、(1)のstatic定義されたポインタことをさしているのか? static宣言されていなくても、theTxt=NULL; のようにポインタにNULLが 代入されていれば同様です。 >(1)の static をつけないで実行すると、正常終了したので... static宣言されていない局所変数は不定ですので、その値は環境によって 変わります。ですからいつも同じ動作となる保証はなく、不定のポインタに アクセスすることも行なってはいけません。 NULLポインタや不定のポインタ、不定の数値を処理してしまうことは ありがちで、C言語のバグのもとになっているケースが 多くみられます。 最近のコンパイラでは、警告レベルを高くしておくと、コンパイルの時点で これらについて警告(Warning)を出すものもあり、注意すると実行前に 気づく場合もありますので、Warningにも注意した方がいいかと思います。
その他の回答 (1)
- HOGERA3
- ベストアンサー率35% (50/139)
>NULL領域というのは、(1)のstatic定義されたポインタことをさしているのか? 「NULL領域」という言葉を聞いたことはありませんが、 たぶんメモリの0番地のことを言っているんでしょう。 「アプリケーションがアクセスしてもいいメモリ領域はここからここまで」 と決まっている(たぶん)から、0番地は触ってはいけない ということだと思います。 static で定義された変数は、明示的に初期化をしなければ 勝手に0に初期化されます。 ですから、 static char *theTxt; とすると、theTxtの値は0になります。 つまり theTxt は0番地を指しているわけです。 そこに strcpy(theTxt,"TEST\n"); によって "TEST\n" を書き込もうとしたから、 「そんなとこ触っちゃイヤ」 というエラーが出たのでしょう。 >(1)の static をつけないで実行すると、正常終了したので、... static をつけないと、初期値としてテキトーな入ります。 正常終了したのは、たまたま触ってもいい領域の値が theTxtに入っていたからではないでしょうか。
お礼
0番地に書き込もうとしたからですね。 やっと意味が理解できました。 ありがとうございました。
お礼
丁寧に答えていただきありがとうございました。 今まで、アドレスを考慮しないで済むプログラミングの世界におりましたので、この回答で理解することができました。