プロが教えるわが家の防犯対策術!

(1)のコードは問題なく動作するのですが、(2)の方はバスエラーとなります。どちらもも引数としてアドレスを渡しているのに何が違うのでしょうか?

(1)
char ch[]="aaaa";
strcpy(ch, "bbbb");
printf("%s\n", ch);
(2)
char *chp="xxxx";
strcpy(chp, "yyyy");
printf("%s\n", chp);

A 回答 (5件)

バスエラーの原因は#1で出ている通りですが、環境によっては文字列リテラルを書き換え可能領域に配置するものがあり、そのような環境では#4で言われているようにバスエラーを起こさずに通ってしまいます。



> char *chp="xxxx";
> chp="yyyy";

これがエラーにならないのは「文字列chpの中身を書き換えている」のではなく、「ポインタ変数chpが指す先を"xxxx"から"yyyy"に変更している」からです。
ポインタの代入とstrcpy()は等価動作ではありません。
    • good
    • 1
この回答へのお礼

なるほど
(1)strcpyで本当にエリアを塗り替えてしまう
(2)ポインタの指し位置を別の場所に変更しているに過ぎない(元の文字列は実はメモリ上残ったまま)

という感じですかね。イメージが湧きました。有り難うございました。

お礼日時:2009/02/15 14:09

1)


char ch[]="aaaa";   //文字配列の領域をプログラムで確保している。
strcpy(ch, "bbbb");
printf("%s\n", ch);
(2)
char *chp="xxxx"; //*chpは"xxxx"をさしているポインタにすぎない。
strcpy(chp, "yyyy"); //"xxxx"の領域はコンパイラが確保した。 
printf("%s\n", chp); //その領域はメモリの不定な場所かも・・
           //chpはその不定な領域を参照(ポイント)・・

char ch[]="xxxx";
char *chp=ch; //この方が「安全」
strcpy(chp,"yyyy");
printf("%s\n",chp);

(2)は処理系によっては通る場合もありますよ。
    • good
    • 0

 


 ごめん。No2は間違い。
 
    • good
    • 0

 


 (1)も(2)も問題あり。
 
    • good
    • 0

(1)のchは書換え可能なメモリ領域を取得するので問題ないです。


(2)の"xxxx"は書換え不可能な定数エリアのようなメモリ領域が取得されます。
よって書換えできない領域を書換えしようとして、バスエラーになります。

この回答への補足

char *chp="xxxx";
//strcpy(chp, "yyyy");
chp="yyyy";
printf("%s\n", chp);

すみません。それでは、上記のように直接文字列を代入すると不可能な定数エリアでも書き換えられるのはなぜでしょうか?

補足日時:2009/02/15 12:24
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!