質問: c言語でstaticを外すと正常な出力の後にゴミが出力されるのはどうしてなのか。原因と対策はあるのか 1. #include 2. int main(void){ 3. static char *wday[3]={ 4. "sunday" 5. ,"monday" 6. ,"tuesday" 7. }; 8. static char **p; 9. p=wday; 10. while(*p){ 11. printf("%s\n",*p); 12. ++p; 13. } 14. return 0; 15. } 上記で、3行目と8行目のstaticを外すとsunday monday tuesdayの後にゴミを出力するのは何故なのか。原因と対策を知りたい。
回答: c言語をやる以上は、配列とポインタは必須なので、しっかり理解するようにしましょう。 char *wday[3] で、char * 3つ分の領域が確保され、 wday[0] = "sunday" の先頭アドレス wday[1] = "monday" の先頭アドレス wday[2] = "tuesday" の先頭アドレス となります。 これを > while(*p){ で、p=&( wday[0] ),&( wday[1]), &( wday[2]) とループを続けます。 このとき、 *p= wday[0] , wday[1], wday[2] となって、文字列のある領域へのポインタになっている、すなわち 0 ではないので、ループが続きます。 そして、 p= wday[3] となります。 さて、 char *wday[3] と宣言したときに、 wday[3] はどうなっているでしょうか? static の場合は、たまたま wday[3]に相当する領域が 0 になっていたのでwhile ループが終了した。 staticが無い場合、たまたま wday[3]に相当する領域が 0 ではないのでループが継続し、 wday[3]の領域に書かれている何かを「アドレス」と判断して、その「アドレス」にある「文字列」を出力します。 続いて、 wday[4],wday[5]...と、 0 になるまでループを繰り返します。 ※ または、途中でosの保護領域へアクセスする等して、エラーになって止まったり、ハードディスク破壊とかも有り得ます。 対策は、「不定な領域へアクセスしないこと」です。 ○ *p でループ判定するのではなく、ループ回数を指定する。 for( i=0 ; i<3; ++i ){〜 等 ○最後に「終り」の印を入れる char *wday[]={ // []の中を省略すると、指定された要素数に合せて自動で設定される "sunday" ,"monday" ,"tuesday" , null // wday[3]にnullを指定する };