なぜ次のことが起こるのですか?
char s[2] = "a";
strcpy(s,"b");
printf("%s",s);
->問題なく実行
char *s = "a";
strcpy(s,"b");
printf("%s",s);
->セグメンテーション違反
2番目のバリエーションも2バイトのメモリを割り当てて、そこs
にコピーするのに十分なメモリがあるべきではありませ"b"
んか?
なぜ次のことが起こるのですか?
char s[2] = "a";
strcpy(s,"b");
printf("%s",s);
->問題なく実行
char *s = "a";
strcpy(s,"b");
printf("%s",s);
->セグメンテーション違反
2番目のバリエーションも2バイトのメモリを割り当てて、そこs
にコピーするのに十分なメモリがあるべきではありませ"b"
んか?
char *s = "a";
ポインタs
は文字列リテラルを指しています"a"
。多くのシステムでは文字列リテラルがプログラムの読み取り専用部分に存在するため、これに書き込もうとすると未定義の動作が発生します。
文字列リテラルがより明確になるのでchar[N]
はなく、型であるというのは歴史の偶然です。const char[N]
2番目のバリエーションもsに2バイトのメモリを割り当てて、そこに「b」をコピーするのに十分なメモリがあるべきではありませんか?
いいえ、char *s
文字列を含む静的メモリアドレスを指しています"a"
(その場所に書き込むと、発生しているセグメンテーション違反が発生します)が、char s[2];
それ自体が文字列に必要なスペースを提供します。
文字列に手動でスペースを割り当てる場合は、動的割り当てを使用できます。
char *s = strdup("a"); /* or malloc(sizeof(char)*2); */
strcpy(s,"b");
printf("%s",s); /* should work fine */
free()
後であなたの弦を忘れないでください。
まったく別の方法/答え:間違いは、ポインターが指す必要のある変数を作成していないため、セグメンテーション違反であると思います。
私が従うルール:ポインタ変数を宣言しても、変数のタイプは作成されません、それは指します。ポインタ変数を作成します。したがって、文字列バッファを指している場合は、文字配列とバッファポインタを指定し、文字配列のアドレスを指す必要があります。