1. ホーム
  2. c

[解決済み】文字列リテラルで初期化された "char *s "に書き込むと、"char s[]"ではなく、セグメンテーションフォールトが発生するのはなぜですか?]

2022-03-28 11:32:31

質問

次のコードは、2行目でseg faultを受ける。

char *str = "string";
str[0] = 'z';  // could be also written as *str = 'z'
printf("%s\n", str);

これは全く問題なく動作しますが

char str[] = "string";
str[0] = 'z';
printf("%s\n", str);

MSVCとGCCでテストしています。

解決方法は?

C言語FAQをご覧ください。 質問1.32

Q : これらの初期化にはどのような違いがあるのでしょうか?

char a[] = "string literal";

char *p = "string literal";

に新しい値を代入しようとすると、プログラムがクラッシュします。 p[i] .

A : 文字列リテラル(正式名称は の二重引用符で囲まれた文字列のことで、C ソース)は、2つの微妙な使い分けができます。 といった具合です。

  1. の宣言のように、charの配列のイニシャライザーとして使用します。 char a[] 初期値を指定します。 は、その配列に含まれる文字(と。 必要であれば、そのサイズも)。
  2. それ以外の場所では、無名の静的な文字の配列に変わります。 そしてこの無名配列は 読み出し専用メモリで、かつ したがって、必ずしも を変更します。式コンテクストでは の場合、配列は一度に ポインタを使用します(第6節参照)。 は、2番目の宣言でpを初期化します。 を指し、無名配列の最初の 要素で構成されます。

一部のコンパイラでは 文字列リテラルが は書き込み可能かどうか(古いバージョンのコンパイルのため コード)、また、いくつかのオプションは 文字列リテラルを形式的に const charの配列として扱われます。 エラーキャッチの向上)