C言語の char x[] と, char *x の違いを理解するためのコードの解答ですが,ポイントは,「領域」にあります.
プログラムは,(色んな分け方がありますが)メモリ上ではいくつかの領域に分かれています.
- コード領域:プログラムのコード本体が入っている領域
- 定数領域:定数(リテラル)のための領域
- スタック領域:変数や関数呼び出しなどに用いられる領域
- ヒープ領域:動的にメモリを確保するとき用の領域
などがあります.
ここで,
int main(){ char x[] = "hoge"; char *y = "hoge"; x[0]='a'; y[0]='a'; return 0; }
の2行目,
char x[] = "hoge";
では,文字列”hoge”5バイト分*1の配列xをスタック領域に確保し,そこへ’h’,’o’,’g’,’e’,’\0’の文字列を格納しています.
それに対して,3行目,
char *y = "hoge";
では,定数領域上に”hoge”という文字列の定数を,スタック上にはchar型のポインタを確保し,そのポインタに,定数領域上の”hoge”の場所を格納しています.
4行目ではスタック上に確保された”hoge”の先頭の文字を’a’に置き換えています.これはOK.
でも5行目では,定数領域上に確保された”hoge”の先頭の文字を置き換えようとしています.
定数領域は書き込み不可なのでここでセグメンテーション違反が起きます.
*1:'h','o','g','e','\0'の5文字.最後はヌル文字で文字列の終端を表す.