次のプログラムでは、 p はポインターとして宣言されています (これは定数ですが、文字列ではありません)。しかし、それでもプログラムは動作せず、「untitled2.exe が動作を停止しました」と言って突然停止します。
#include<stdio.h>
#include<stdlib.h>
int main(){
char * const p = "hello";
*p = 'm';
return 0;
}
この予期しない動作はなぜですか?
char * const p = "hello";
定数ポインタを定義し、本質的に 型でp
ある定数文字列のメモリ アドレスで初期化します。この割り当てにより、修飾子を破棄しています。これは有効な C ですが、何をしているのかわからないと未定義の動作につながります。"hello"
const char *
const
指しconst char *
ているメモリの内容を変更することは禁止されていますが、アドレスを変更することは禁止されていませんがchar * const
、内容を変更することは許可されていますが、アドレスは固定されています。コンボバージョンもありconst char * const
ます。
これは有効な C コードですが、OS の配置と制限によっては"hello"
、書き込み可能なメモリになる場合とそうでない場合があります。これは未定義のままです。経験則として、定数文字列は実行可能プログラムのテキストの一部であり、読み取り専用です。したがって、書き込みを試みると*p
、メモリ パーミッション エラーが発生しますSIGSEGV
。
正しい方法は、文字列の内容をスタックにコピーしてそこで作業することです。
char p[] = "hello";
*p
読み取り/書き込み可能なスタック上にあるため、変更できるようになりました。グローバルに同じものが必要な場合は、グローバル スコープに入れます。