• ベストアンサー

ポインタです

#include <stdio.h> char *msg = "This is an apple."; void exchange(char *); int main(void){ char *mm = "This is a test."; char *p = msg; printf("%s\n", p);//This is an apple. p = mm; printf("%s\n", p);//This is a test. exchange(p); printf("%s\n", p); return 0; } void exchange(char *q){ q[0] = 't'; } としたら"This is a test." が "this is a test." に変わっているはずなんですがCygwinでの表示は Segmentation fault (core dumped)と表示されてしまいます・・・ なにが原因なんでしょうか?

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

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.5

★原因は文字列定数を書き換えたから。 ・もう既に4つの回答者のコメントから分かると思いますが、文字列定数の内容を  書き換える操作を『exchange』関数が行っているから『セグメントのエラー』が  表示されたのです。 ・よって、2つの文字列を『char *msg = "文字列";』のポインタで定義するのでは  なく配列で『char msg[] = "文字列";』と定義すれば問題は起きません。 ・つまり、  『char msg[] = "This is an apple.";』  『char mm[] = "This is a test.";』  と配列の[]に編集するだけでOK! 余談: ・昔、MS-DOS の時代では質問者さんの『exchange』関数でも正常に文字列定数の  内容も書き換えできます。でも、今は Windows 時代になってメモリのデータを  やたらにポインタで書き換えできない時代です。ある意味『セグメントエラー』  が出てくれた方が安全です。まぁとにかく文字列定数は『定数』であり『変数』  のように書き換えできない不変のものと考えましょう。 ・以上。おわり。

すると、全ての回答が全文表示されます。

その他の回答 (4)

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.4

exchange()関数に、固定の文字列(static文字列)へのポインタを渡し、そのポインタの中身を書き換えようとしています。 通常、このような操作は禁止されています。普通はこれを「人に言えない恥かしいバグ」と呼びます。 「"」で括った文字列は、読み出し専用メモリ(読み込みのみ許され、書き込みが許されないメモリセグメント)に配置されます。 その文字列に対し書き込みを行えば、当然、CPUが「メモリセグメントのアクセス違反」を検出し、例外が発生しプログラムがアボートします。 その「例外が発生しプログラムがアボートした」と言う表示が「Segmentation fault (core dumped)」と言う表示です。 なお、例外が発生してアボートすると、例外発生時のメモリの内容、CPUが実行していたアドレス、レジスタの値などが「core」と呼ばれるファイルにダンプされます。それが「(core dumped)」の表示の意味です。カレントディレクトリに「core」と言うファイルが作られてるので確認して下さい。 文字列の中身を書き換えたいなら int main(void){ char *mm = "This is a test."; char p[256]; strcpy(p,msg);//p = msg;の代り printf("%s\n", p);//This is an apple. strcpy(p,mm);//p = mm;の代り printf("%s\n", p);//This is a test. exchange(p); printf("%s\n", p); return 0; } のように、書き換える対象をオート変数の(無論、充分な大きさを確保した)配列にするか、malloc関数などで動的に確保した領域にしないとならない。(mallocしたメモリはfreeで開放する事)

すると、全ての回答が全文表示されます。
  • mac_res
  • ベストアンサー率36% (568/1571)
回答No.3

constantな文字列を書き換えようとしているからです。 #include <stdio.h> #include <string.h> void exchange(char *q) { q[0] = 't'; } int main(void) { char mm[80]; char *p = mm; strcpy(mm,"This is an apple."); printf("%s\n", p); //This is an apple. strcpy(mm,"This is a test."); printf("%s\n", p); //This is a test. exchange(mm); printf("%s\n", p); return 0; }

すると、全ての回答が全文表示されます。
noname#39970
noname#39970
回答No.2

> char *mm = "This is a test."; char mm[] = "This is a test.";

すると、全ての回答が全文表示されます。
  • black2005
  • ベストアンサー率32% (1968/6046)
回答No.1

char *msg = "This is an apple."; これは文字列定数と呼ばれ、文字列の内容を変更すると結果は不定となります。(早い話、変更不可) 変更したいなら、 char msg[] = "This is an apple."; として配列として宣言、初期化しなければなりません。

すると、全ての回答が全文表示されます。

関連するQ&A