- ベストアンサー
文字列を表すための配列とポインタ
- 配列とポインタを使用して文字列を表すプログラムで問題が発生しています。配列型文字列は正常に動作しますが、ポインタ型文字列はエラーが発生してしまいます。
- プログラム実行時に「初期化されていないローカル変数」の警告が表示されます。また、ポインタ型文字列の実行後にプログラムが停止し、エラーとして終了してしまいます。
- 問題の原因は「char *b;」というポインタの宣言部分ですが、具体的な理由はわかりません。解決策を教えていただきたいです。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
「初期化されていないローカル変数'b'が使用されます」 b にアドレスを代入してあげましょう。 #include <stdlib.h> b = (char*)malloc(256);
その他の回答 (6)
- D-Matsu
- ベストアンサー率45% (1080/2394)
「コード上は同じように扱えるが別のもの」であることを理解してないとこうなります。 私も同じことをやった時期がありました。 char a[256]; は「aという名前のchar配列(要素数256)」であるのに対し char *b; は「bという名前のcharポインタ」です。 ポインタは、その先に示すものが正しく存在しないと機能しません。 この場合はaとは異なるchar配列を定義するか、あるいはmalloc()等の動的メモリ確保を利用するかしてbの参照先を用意する必要があります。
お礼
ありがとうございます。
- ryu_chan
- ベストアンサー率37% (69/186)
char a[256]; → 256バイトのメモリが確保される char *b; → メモリは確保されない(メモリの番地を入れておくぶんは確保されます) bは単にメモリの番地を入れておく変数で、char *b;と宣言してもメモリ自体は確保されません。なので、他の回答者が回答されているようにmalloc関数等でメモリを確保してから、そのメモリの先頭番地をbに入れてください。 scanf("%s", b);は、bで示されている番地のメモリに標準入力(キーボード)から入力された値を入れます。なので、その入力した値を入れるメモリ領域が必要なのです。
お礼
char *b; のあとには、bへの何らかの代入操作が必要なようですね、自分でもいろいろポインタの初期化について調べてみました。言葉で説明すると、抽象的でどうも私には分かりにくいです。ありがとうございました。
- savitch201
- ベストアンサー率66% (2/3)
char a[256]; char *b; printf等で出力した場合、aはa[256]の先頭アドレスを出力します。 一方、bはcharデータのアドレスを格納する変数です。 質問にあるプログラムで、scanfでbの指すアドレスに文字列を格納するにはまずbにメモリ領域の先頭アドレスを代入する必要があります。例えば、a[256](stackにある配列)に文字列を格納したいなら、 b=a; scanf("%s", b); とすればよいと思います。 また、動的メモリ領域(heap)に格納したいなら、他の回答にもあるようにmallocまたはcallocを使ってまずメモリ領域を確保してからscanfを使えばいいと思います。 つまり、bが確保されているメモリ領域(stackでもheapどちらでも)を指していればコンパイラもOSも文句はいいません。質問にあるプログラムではbは初期化されていないので、scanf("%s", b);でランタイムエラーが発生します。 コンピュータアーキテクチャ、stack、heap等を勉強してみるとこういう問題がわかってくると思いますよ。 あと、mallocを使った場合は、free(b)でメモリを解放する必要があります。
お礼
>コンピュータアーキテクチャ、stack、heap等を勉強してみるとこういう問題がわかってくると思いますよ。 >あと、mallocを使った場合は、free(b)でメモリを解放する必要があります。 そういう勉強をしたいものです。それから、free(b)についてのご指摘も、ありがとうございました。
- Tacosan
- ベストアンサー率23% (3656/15482)
あ, すみません, #3 の「たまたま配列をあたかも (定数) ポインタのように使える場合がある」は間違いです. 正しくは たまたま配列指示子をあたかも (定数) ポインタのように使える場合がある です. 「配列指示子」はわかりにくいので (多少不正確ではあるが) たまたま配列名をあたかも (定数) ポインタのように使える場合がある と思ってもいい. いずれにしても, 本質的に配列とポインタとは違うものです.
お礼
ありがとうございます。
- Tacosan
- ベストアンサー率23% (3656/15482)
「配列とポインタは同様に扱えるもの」という思い込みは捨ててください. 配列とポインタは全く別物です. 「たまたま配列をあたかも (定数) ポインタのように使える場合がある」だけ.
お礼
はい。分かりました。
- asuncion
- ベストアンサー率33% (2127/6289)
>二行に分ければよいのか、 >一行にまとめてよいのか 【2行に分けねばならない場合】 char *b; /* 何かの文(1個以上) */ b = malloc(256); 【1行でよい場合】 char *b = malloc(256); 【2行でよい場合(定義の直後に代入)】 char *b; b = malloc(256); 他の型の変数の場合と、何ら変わりません。
お礼
ありがとうございます。よく分かりました。
補足
ありがとうございます。 もう少し詳しく教えていただけませんでしょうか。すなわち、 char *b; b = (char *)malloc(256); と二行に分ければよいのか、 char *b = (char *)malloc(256); と一行にまとめてよいのか(済みません、よく分かっていません)、よろしくお願いします。 それから、このように文字列を使うときは、ポインタより配列を使う方がよいのでしょうか。よろしくお願いします。