ソースコードに「文字列」を書き込むと、コンパイル時にその値を知る必要があるため、実行可能ファイルに直接書き込まれます (ソフトウェアを分離して、その中のすべてのプレーンテキスト文字列を見つけるためのツールがあります)。 09
と書くと 、「これは文字列です」の場所は実行可能ファイルにあり、場所は 11
を指し、実行可能ファイルにあります。実行可能イメージのデータは読み取り専用です。
あなたがする必要があるのは(他の答えが指摘したように)ヒープ上またはスタックフレーム内の読み取り専用ではない場所にそのメモリを作成することです。ローカル配列を宣言すると、その配列の各要素に対してスタック上に領域が作成され、(実行可能ファイルに格納されている) 文字列リテラルがスタック内のその領域にコピーされます。
char a[] = "This is a string";
ヒープにメモリを割り当ててから 28
を使用して、そのデータを手動でコピーすることもできます 文字列リテラルをそのスペースにコピーします。
char *a = malloc(256);
strcpy(a, "This is a string");
38
を使用してスペースを割り当てるときはいつでも 45
を呼び出すことを忘れないでください あなたがそれを終えたとき(読んでください:メモリリーク)。
基本的に、データがどこにあるかを追跡する必要があります。ソースに文字列を書き込むときはいつでも、その文字列は読み取り専用です (そうしないと、実行可能ファイルの動作が変わる可能性があります。 そして 68
を変更しました 72
まで .それからどこかで 85
と書いた . 97
の最初の文字を変更できる場合 、そしてあなたのコンパイラはそれを一度だけ保存しました(そうすべきです)、その後 104
117
を出力します !)
いいえ、文字列は読み取り専用メモリに保存できるため、変更することはできません。変更したい場合は、代わりに配列を使用できます。例:
char a[] = "This is a string";
または、malloc を使用してメモリを割り当てることもできます。
char *a = malloc(100);
strcpy(a, "This is a string");
free(a); // deallocate memory once you've done
多くの人は、C の文字列リテラルに関連して char* と char[] の違いについて混乱しています。
char *foo = "hello world";
...実際には foo がメモリの定数ブロックを指しています (実際、このインスタンスでコンパイラが "hello world" に対して行うことは実装に依存します)。
代わりに char[] を使用すると、配列を作成してその内容を "hello world" で埋めることをコンパイラに伝えます。 foo は、char 配列の最初のインデックスへのポインタです。どちらも char ポインターですが、ローカルに割り当てられた変更可能なメモリ ブロックを指すのは char[] だけです。