• ベストアンサー

strcpyについて

下記のコードはpの容量が分からないのにstrcpy()を実行しています。 #include <iostream.h> int main() { char *p = "a"; strcpy(p,"bbbbbbbbbbbbbbb"); cout << p; return 0; } エラーにならなかったのですが、このコードはこれでいいんですか? この場合、strcpy()の第2引数は相当長い文字列へのポインタでも大丈夫なんですか?

質問者が選んだベストアンサー

  • ベストアンサー
noname#25358
noname#25358
回答No.4

 ちなみに補足。  C言語では、「出力先のメモリの容量が分からない」という状況は許されません。  何らかの方法で必ず調べなければいけません。  質問文中の方法だと、出力元のメモリサイズは分かるわけですから、必要なサイズ分だけ先に malloc 等で確保する必要があります。  また、質問文中の "a" は、メモリ構造上は const 型です(代入先の p は const ではありませんが)。何が起こるか分からないので上書きしてはいけません。 #include <iostream.h> #include <malloc.h> int main() { char *p; p = (char*)malloc( strlen("bbbbbbbbbbbbbbb") ); strcpy(p,"bbbbbbbbbbbbbbb"); cout << p; free(p); return 0; }  これだとうまくいきます。 >strcpy()の第2引数は相当長い文字列へのポインタでも  問題ありません。

amurit
質問者

補足

ありがとうございます。 回答の最後の、問題ないというのはmallocした場合のことでしょうね。 mallocのソースもありがとうございます。 #include <malloc.h> は無しでも動きました。

その他の回答 (3)

  • MovingWalk
  • ベストアンサー率43% (2233/5098)
回答No.3

>このコードはこれでいいんですか? 良くありませんね。 受け側の領域が文字列サイズ+1以上になっていなければ、動作は保証されません。 それは、プログラマの責任で確保しなければいけません。 セキュリティホールの原因となっているのがgets()という関数というのを ご存知でしょうか?  この関数は受取るサイズを制限できないので、受け側の領域を安全に確保する ことができないのです。ですから、コンパイラによっては「危険な関数」として 警告を出す場合があります。変わりにfgtes()などを使うのが推奨されます。

amurit
質問者

お礼

gets()のことも知りませんでした。ありがとうございました。

回答No.2

こんにちは。 「エラーにならなかった」とはコンパイルエラーにならなかった?? それとも、標準出力にbbbbbbbbbbbbbbbと出た?? もちろん、エラーは起こらず、bbbbbbbbbbbbbbbは出力されます。 しかし、No.1さんの言うとおり、他の変数の領域を壊しています。 strcpyはコピー元に(ソースをコピーするための)十分なバッファを 用意する必要があります。 このプログラムだけを考えると正常に動いていますが、 壊された領域を使っている他のプログラムに動作の保証がありません。 その場合、「他のプログラム」が、バグっていると考えてしまいますし。

amurit
質問者

お礼

静的確保とか動的確保した変数でないとstrcpy()してはいけないですよね。 ありがとうございました。

  • taknt
  • ベストアンサー率19% (1556/7783)
回答No.1

場合によっては 暴走する可能性があると思います。 また、他の変数の領域を壊していることも考えられます。