2

ウィキペディアでこれを読んだ

    int main(void)
 {

    char *s = "hello world";
    *s = 'H';

 }

このコードを含むプログラムがコンパイルされると、読み取り専用としてマークされたプログラム実行可能ファイルのセクションに文字列「hello world」が配置されます。読み込まれると、オペレーティング システムはそれを他の文字列や定数データと共にメモリの読み取り専用セグメントに配置します。実行されると、変数 s が文字列の位置を指すように設定され、変数を介して H 文字をメモリに書き込もうとするため、セグメンテーション フォールトが発生します**

文字列が読み取り専用セグメントに配置されている理由がわかりません。誰かがこれを説明してください。

4

5 に答える 5

3

次の間には大きな違いがあります。

char * s = "Hello world";

char s[] = "Hello world";

最初のケースでsは、変更できないものへのポインターです。読み取り専用メモリ (通常は、アプリケーションのコード セクション) に格納されます。

後者の場合、変更可能な読み取り/書き込みメモリ (通常はプレーン RAM) に配列を割り当てます。

于 2013-01-24T10:43:18.620 に答える
3

文字列リテラルは読み取り専用メモリに保存されます。これがまさにそのように機能します。あなたのコードは、文字列リテラルが格納されているメモリを指すように初期化されたポインタを使用しているため、そのメモリを有効に変更することはできません。

変更可能なメモリ内の文字列を取得するには、次のようにします。

char s[] = "hello world";

定数文字列を使用して非定数配列を初期化しているだけなので、問題ありません。

于 2013-01-24T10:42:03.017 に答える
2
  • When you do: char *s = "hello world";thensは、コード部分にあるメモリを指すポインターであるため、変更できません

  • When you do: char s[] = "Hello World";thensは、スタック 上にある文字の配列であるため、変更できます。

プログラム中に文字列を変更したくない場合は、次のようにすることをお勧めしますchar const *s = ....;。次に、文字列を変更しようとすると、プログラムはセグメンテーション違反でクラッシュせず、コンパイラ エラーが発生します(これははるかに優れています)。

于 2013-01-24T10:41:07.553 に答える
0

最初にポインターをよく理解してください。短いデモを紹介します。

まず、コードを 1 行ずつ分析してみましょう。メインから始めましょう

char *s = "Some_string";

まず第一に、char 変数へのポインターを宣言しています。現在 *s はメモリ内のアドレスです。メモリ値を変更しようとすると C はあなたを蹴ります。 s をそのアドレスに変更してから、s を変更します。

あなたが得ることを願っています、それ。詳細な参照と詳細な理解については、KN King: C プログラミングの最新のアプローチを参照してください。

于 2013-01-24T11:29:34.827 に答える
0

言語定義によると、文字列リテラルは、その有効期間がプログラムの有効期間を超えて延長され、プログラム全体で表示されるように格納する必要があります。

文字列が格納される場所に関してこれが正確に何を意味するかは、実装次第です。言語定義は、文字列リテラルが読み取り専用メモリに格納されることを義務付けておらず、すべての実装がそうしているわけではありません。文字列リテラルの内容を変更しようとすると、未定義の動作が発生するということだけが示されています。つまり、実装は自由に好きなことを行うことができます。

于 2013-01-24T15:43:56.653 に答える