人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

プログラミング初心者です

ポインタを使った文字列の初期化でつまづいています.
char str[] = "hoge";
char* str2 = "piyo";
のように初期化した後では

printf("%c\n",str[0]); ->hが出力
printf("%c\n",str2[0]); ->pが出力

となるのですが,

str[0] = 'A'; <-OK
str2[0] = 'A'; <-エラー
とするとプログラムが落ちてしまいます.

ポインタの知識が乏しいのか,このエラーの原因がわかりません.
なにか参考になるページがありましたら教えていただけないでしょうか?

よろしくお願いいたします.

●質問者: rockafeller
●カテゴリ:コンピュータ インターネット
✍キーワード:Char hoge STR エラー プログラミング
○ 状態 :終了
└ 回答数 : 4/4件

▽最新の回答へ

1 ● TONTON3
●20ポイント

char str[] = "hoge";

char* str2 = "piyo";

str2に文字というか数値を格納する場合

メモリを割り当てたり strのポインタにすればよいでしょう

str2 を maloc してみてはいかがでしょうか?

◎質問者からの返答

ありがとうございます.

malocを使うと正常に動作しました.


2 ● Mook
●30ポイント

前者は動的領域にデータが確保されるので、

char str[] = "hoge";

char str[5] = { 'h', 'o', 'g', 'e', '\0' };

と等価ですが、後者はコンパイラによって定義されたデータ領域を指すポインタなので、その領域を変更することは動作的に正しくません。


コンパイラによって動くこともあるかもしれませんが、それは偶然(コンパイラの仕様)であって、データが静的領域を指す場合、今回のように access violation で落ちても、それは正常な動作です。


C言語 ポインタ完全制覇

C言語のポインタ

◎質問者からの返答

データ領域という概念を知りませんでした.

ありがとうございました.


3 ● くまっぷす
●30ポイント ベストアンサー

たぶん、実行時エラーとしてセグメンテーションエラーが出たのだと思います。

char str[] = "hoge";
char* str2 = "piyo";

上の行は"hoge"という文字列を「データ格納領域(データセグメント)」にある配列strにコピーします。

下の行は"piyo"という文字列が書かれた「プログラム格納領域(コードセグメント)」のアドレスをstr2に代入します。

一般にプログラム格納領域は変化してはいけない(読み出しのみ)になっているために書き込みをしようとするとOS(CPU)がエラーを出すのです。

これが組み込み用の8bitマイコンなんかだとそういうセグメントの概念がないのでたぶんエラーは出ないです。

もしポインターでやるのなら

char* p = malloc(5);

strcpy( p, "piyo");

みたいにポインタが、メモリ割り当て関数malloc()で割り当てられたデータ格納領域を指すようにするなどの必要があります。

http://itpro.nikkeibp.co.jp/article/COLUMN/20061023/251565/?ST=d...

http://itpro.nikkeibp.co.jp/article/COLUMN/20061128/255135/?ST=d...

◎質問者からの返答

char str[] = "hoge";

char* str2 = "piyo";

では同じことをしているのかと思っていたのですが,全然意味が違うのですね・・・


4 ● dev_zer0
●30ポイント

おそらくC言語だと思われますが、下記のC-FAQ 1.32を参照してください

http://www.kouno.jp/home/c_faq/c1.html#32


> char str[] = "hoge";

> str[0] = 'A'; <-OK

これは5つの要素を持つ配列を定義してその0番目を書き換えただけなので問題ありません

# str[5] = 'A';とかすると未定義動作になります

# 未定義動作とは「何が起こってもよい」ということです

# 別のコンパイラだとプログラムが落ちない可能性もありますし、

# コンパイルオプションの変更や、何か処理を追加するだけで

# 動いたり、動かなくなったりします。


> char* str2 = "piyo";

> str2[0] = 'A'; <-エラー

これは文字列リテラルを指すポインタを定義して、

文字列リテラルを書き換えてしまったので未定義動作となります。


ポインタを使うときはその指し示す先に何があるのかを意識する必要があります。

◎質問者からの返答

ありがとうございました.

後者の書き方だと,ポインタの先が文字列リテラルのアドレスになるということがわかりました.

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ