
文字列を表すための配列とポインタ
配列とポインタは同様に扱えるもの、と思って、次のプログラムを作りました。処理系は、Visual Studio 2010 コマンドプロンプトです。
#include <stdio.h>
void main(void)
{
char a[256];
char *b;
printf("文字列を入力してください。\n");
printf("例「abcde」\n\n");
printf("配列型文字列を使います。\n");
scanf("%s", a);
printf("文字列は%sです。\n\n", a);
printf("ポインタ型文字列を使います。\n");
scanf("%s", b);
printf("文字列は%sです。\n", b);
}
すると、まずコンパイル時に、
「warning C4700: 初期化されていないローカル変数'b'が使用されます」
と表示されました。そして、実行すると、「配列型文字列」の方は問題ないのですが、「ポインタ型文字列」の方の実行後に、
「x.exeは動作を停止しました。
問題が発生したため、プログラムが正しく動作しなくなりま
した。プログラムは閉じられ、解決策がある場合は
Windowsから通知されます。」
と表示され、エラーとして終了してしまいます。
「char *b;」
と宣言するところが問題のようですが、なぜなのかが分かりません。どなたか、解説をお願いします。
No.1ベストアンサー
- 回答日時:
「初期化されていないローカル変数'b'が使用されます」
b にアドレスを代入してあげましょう。
#include <stdlib.h>
b = (char*)malloc(256);
この回答への補足
ありがとうございます。
もう少し詳しく教えていただけませんでしょうか。すなわち、
char *b;
b = (char *)malloc(256);
と二行に分ければよいのか、
char *b = (char *)malloc(256);
と一行にまとめてよいのか(済みません、よく分かっていません)、よろしくお願いします。
それから、このように文字列を使うときは、ポインタより配列を使う方がよいのでしょうか。よろしくお願いします。
No.7
- 回答日時:
「コード上は同じように扱えるが別のもの」であることを理解してないとこうなります。
私も同じことをやった時期がありました。
char a[256];
は「aという名前のchar配列(要素数256)」であるのに対し
char *b;
は「bという名前のcharポインタ」です。
ポインタは、その先に示すものが正しく存在しないと機能しません。
この場合はaとは異なるchar配列を定義するか、あるいはmalloc()等の動的メモリ確保を利用するかしてbの参照先を用意する必要があります。
No.6
- 回答日時:
char a[256]; → 256バイトのメモリが確保される
char *b; → メモリは確保されない(メモリの番地を入れておくぶんは確保されます)
bは単にメモリの番地を入れておく変数で、char *b;と宣言してもメモリ自体は確保されません。なので、他の回答者が回答されているようにmalloc関数等でメモリを確保してから、そのメモリの先頭番地をbに入れてください。
scanf("%s", b);は、bで示されている番地のメモリに標準入力(キーボード)から入力された値を入れます。なので、その入力した値を入れるメモリ領域が必要なのです。
char *b;
のあとには、bへの何らかの代入操作が必要なようですね、自分でもいろいろポインタの初期化について調べてみました。言葉で説明すると、抽象的でどうも私には分かりにくいです。ありがとうございました。
No.5
- 回答日時:
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)についてのご指摘も、ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# str[j++]の意味 2 2022/08/30 16:20
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# 【C言語】全角文字の配列を、全角のまま1文字ずつ出力する方法 4 2023/05/09 15:08
- C言語・C++・C# c言語 コマンドライン引数 4 2023/02/09 18:47
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
プログラミングについて。 1つ...
-
gccを行ってもexeファイルが生...
-
c言語
-
visual studio 2022でのC#プロ...
-
C# DatagridviewにExcelシート...
-
mallocについて
-
C言語って古いですか?
-
C言語関数違いについて。
-
逆コンパイルと逆アセンブルの...
-
プログラムの実行時に'<'でリダ...
-
パソコン
-
CPUが16bitでも32bitOSでコンパ...
-
Python、プログラミングについ...
-
だれがとけるの?
-
バッチファイルで以下のような...
-
Notepad++の関数リスト表示の変...
-
VisualStudio2022でC言語プログ...
-
License='MIT' ってなんでmitな...
-
C言語 ストリームについて。
-
c言語でイベントフラグを使った...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
c言語
-
gccを行ってもexeファイルが生...
-
大量のデータを読み込んで表示...
-
visual studio 2022でのC#プロ...
-
C++でデスクトップGUIアプリ開...
-
【C言語】全角文字の配列を、全...
-
Windows Formアプリからコンソ...
-
VisualStudio2022でC言語プログ...
-
C#でログファイルにファイルパ...
-
C#でTreeViewのCheckBoxのサイ...
-
c#のTLS1.2での通信について
-
VisualStudioでC++クラスを追加...
-
C言語について。
-
int16_t の _t は何?
-
プログラマー達は何故、プログ...
-
逆コンパイルと逆アセンブルの...
-
C言語の関数のextern宣言
-
c言語でイベントフラグを使った...
-
C言語 関数、変数の宣言について
-
[C言語]fputsとfprintfの違い
おすすめ情報