以下が機能しない理由について当惑しています:
char * f = "abcdef";
strcpy(f, "abcdef");
printf("%s",f);
char s[] = "ddd";
strcpy(&s[0], "eee");
printf("%s", s);
両方の例で strcpy は char * を受け取りましたが、最初の例では恐ろしい死に方をしました。
"abcdef"
"ddd"
アドレス空間の読み取り専用セクションに存在する可能性のある文字列リテラルです。char s[] = "ddd"
このリテラルが確実にスタックにコピーされるため、変更可能です。
char * f = "abcdef";
読み取り専用領域にある「abcdef」への char ポインターを定義するため、この場所に書き込むことはできません
char s[] = "ddd";
書き込み可能なスタック上のchar 配列を定義します。
最初の例では、文字列リテラルへのポインターがあります。const char *
文字列リテラルを変更しようとする試みは未定義の動作であるため、このポインターは実際にはである必要があります。ただし、従来の理由により、 a を使用しchar *
てそれを指すことができます。しかし、それでも変更しようとしてはいけません。
2番目のバージョンでは、ボグ標準の配列があり、その内容はたまたま文字列と同等になるように初期化されています。これは配列であるため、変更可能です。
最初の例は achar *
から文字リテラル (リテラルは"something"
) です。文字リテラルは読み取り専用であり、それらに書き込もうとするとクラッシュする可能性があります。最初のポインターは実際には である必要がありますがconst char *f = "abcdef";
、これstrcpy
はかかりません。
このステートメントchar * f = "abcdef"
は、メモリ内のポイントをリテラル文字列「abcdef」に割り当てますが、メモリが動的に割り当てられるまでその内容を変更することを拒否します - これはconst char
.
あなたがしているのは、メモリ内にポインタを作成し、次の 6 バイトを上書きすることだけですが、これは C では違法です。
文字列リテラルはほとんどのコンパイラで読み取り専用と見なされるため、文字列リテラルが存在するメモリが読み取り専用としてマークされ、実行時エラーが発生する可能性があります。
機能させるには、次の手順を実行します。
char * f = strdup("abcdef");
strcpy(f, "abcdef");
printf("%s",f);
free(f);
これにより、変更可能な文字列のコピーがヒープ メモリに作成されます。これはもちろん、プログラムの最後に解放する必要があります。