- ベストアンサー
ポインタへの値の代入時の警告の原因
私は現在、事務職をやっており、プログラミングとは全く別の畑に居ます。 真剣に転職を考えておりC言語を独学にて勉強中なのですが、ポインタの勉強中、どうしても理解できない点がありましたので質問いたしました。 ポインタを理解するために下記1~3のような処理をさせました。 1.文字変数s に 'a' を代入 2.ポインタp を宣言し、変数s のアドレスを代入 3.最終的にpの値を確認する。 #include<stdio.h> int main (void) { char s; char *p; s = ' a '; p = & s; //←ここが9行目です printf (" pは %c です\n " , *p); return 0; } すると、 『 pは a です 』 と、期待通りの表示がされました。 次に、9行目を *p = s と書き換えた所、コンパイル時に 『値が割り当てられていないローカルな変数’p’に対して参照が行われました』 と言う警告が表示されました。 実行してみた所、 『pは a です』 と、結果は期待通りのものが表示されたのですが、この警告がなぜ表示されたのかが分かりません。 参考書を読んでも、このような(*p = sのような)書き方は載ってましたし、私自身、『「ポインタ変数pの値*p」に「変数sの値」を代入した。』と認識している為、間違いでは無いと考えております。 この警告がなされた原因について、どなたかご存知でしたら、宜しくお願いいたします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
char *p; と宣言しただけでは どこのメモリーも参照していません # 実行時にポインタpに割り当てられたメモリの内容に依存します ポインタ変数は必ず 初期化作業が必要です p = &a; とすることで ポインタpが 変数aを指すポインタとして機能します どこを指しているかわからないポインタに対して その中身を書き換えると 思わぬところを書き換えてしまいます 下手をすると OSを壊してしまったりしますので注意が必要です また Cでは ポインタとポインタの示す先を関連付けて管理しませんので以下のようなソースはコンパイルできるものの 実行時におかしな動作をする場合があります char buf[256]; char *p = buf; *(p+257) = 'a'; pが指している bufは256しか確保していないので p+257はbufで確保した領域を超えています 別の変数など領域を書き換えてしまうことになります
その他の回答 (2)
- jacta
- ベストアンサー率26% (845/3158)
既に回答も出ているのですが、間違った使い方をしているのに、なぜ期待通りの動作をしたかについて説明します。 char *p; と宣言した時点で、pは初期化されていないため、変数にはゴミが入っています。pはどこもポイントしていないわけではなく、そのゴミの値に基づいて、どこか知らないところをポイントしているのです。 そして、 *p = c; とすることで、pがポイントしていたどこか知らない場所にcの値が格納されます。 printf (" pは %c です\n " , *p); での*pは、どこだか分からないけれど、とりあえず格納された値を取り出します。場所はどこか分かりませんが、そこには先ほどcの値を格納したので、取り出される値は(*pに代入した時点での)cの値になります。 pがポイントしているどこだか分からない場所によっては、そもそも書き込みがどきなかったり、メモリがなかったり、場合によって特殊な機能を持っていたりすることもあるので、必ずしも期待通りの動作になるとは限りません(一般的にはまともに動作しません)。
お礼
納得いたしました。 早速のご回答、誠に有難うございました。
これは初心者が良く間違う点です。 char *p; は、pはポインタですといっているだけででメモリ領域がセットされていません。 例えば、 int a; は、aという変数のためにintの領域を割り当てますという宣言でメモリ領域がセットされています。 従って、 char *p; としただけでは、pのアドレスが確定しておらず(不定)、例えばすでにメモリ領域が確定している変数をつぶしたりして、危険です。 一つの方法として、 char a; でメモリ領域を確保し、 char *p; として、 p=&a としてpのアドレスを確定する必要があります。
お礼
納得いたしました。 早速のご回答、誠に有難うございました。
お礼
なるほど、納得しました。 言われてみれば、書き換えたことによって「ポインタ変数*P」の指すアドレスがなくなってました。 どうしても「*P = s」と言う記述を使用したければ、その前に必ず「p = &a(任意の変数)」と宣言しなけばいけないと言うことですね。 有難うございました。