-2

これは機能します:

int main()
{      
    char *t = "Hello";
    t = "World";
    printf("%s", t);
}

しかし、これはセグメンテーション違反を引き起こします:

int main()
{   
    char *t = "Hello";   
    strcpy(t, "World"); // the only difference
    printf("%s", t);
}

なんで?

4

7 に答える 7

4

たとえば、明示的に定義する文字列"Hello"は、通常、読み取り専用メモリの領域に配置されます。これらの文字列は変更できません。

最初の例では、"Hello" 文字列を "World" 文字列に変更していません。「Hello」ではなく「World」を指すtように再割り当てしています。「Hello」文字列は、読み取り専用メモリ内にそのまま残っています。

初期状態は次のとおりです。

t -> "Hello"
     "World"

2 番目の状態は次のとおりです。

     "Hello"
t -> "World"

2 番目の例では、"Hello" 文字列を上書きしようとしています。これはできません。

char *t宣言を からに変更する必要がありますconst char *t。これを強制するようにGCCを構成できると思います。

于 2013-08-22T19:10:53.010 に答える
3

最初の例では、ポインタtは文字列定数を指すように作成され"Hello"、その後すぐに文字列定数を指すようになります"World"。後者の値が出力されます。

2 番目の例のコードは、文字列定数が書き込み可能でないため、segfault でクラッシュします。(strcpy は、テキストを保持するメモリを変更しようとします"Hello")。でコンパイルされていない限り、GCC は文字列定数を読み取り専用セクションに配置し-fwriteable-stringsます。

コード

char *test = "Hello";

は、コンパイラとリンカーがバイト文字列 "Hello\0" を読み取り専用セクションに配置し、testポイントをその最初の文字に配置することを意味します。このポインターを介して書き込みを試みると、オペレーティング システムによって厳しく処罰されます。

一方で

char test[] = "Hello";

( ) の初期値を持つ 6 文字の配列を宣言します{ 'H', 'e', 'l', 'l', 'o', '\0' }

一部の古いプログラムでは、文字列定数が書き込み可能であると想定されていました。したがって、GCC は-fwriteable-stringsコマンド ライン スイッチを使用してこれらのプログラムのコンパイルをサポートする必要があります。

于 2013-08-22T19:08:17.127 に答える
3

1 つ目は、 の値をtのアドレスから のアドレスに"Hello"変更します"World""Hello"2 番目は、データ自体を上書きしようとします。

于 2013-08-22T19:10:34.130 に答える
2

読み取り専用の場所にchar *t="Hello" t「Hello」を割り当てます。したがって、読み取り専用の場所に書き込むと、セグメンテーション違反が発生します。

割り当てとコピーには違いがあります。

最初の例では、別の文字列のアドレスを に割り当てようとしていますt

2 番目の例では、読み取り専用の場所に書き込もうとしています。

char を使用しますt[] = "Hello"。ここで t は上書きできます

詳しい説明はこちら

于 2013-08-22T19:11:40.400 に答える
2

割り当てt = "World"はポインターのみをstrcpy変更しますが、 は t が指すメモリを変更します。文字列リテラルは、読み取り専用セグメントに存在する場合があります。

于 2013-08-22T19:12:02.463 に答える
2

char* tポインタです。最初の例では、ある文字列リテラルから別の文字列リテラルへのポインターを割り当てているだけです。最初tに を指し"Hello"、次に を指してい"World"ます。これは完全に合法です。

ただし、文字列リテラル自体はリテラルであり、変更することはできません。通常、それらはメモリの読み取り専用セクションにあります。"Hello"2 番目の例では、文字列リテラルに割り当てられたメモリの内容を で上書きして変更しようとしてい"World"ます。これは違法であり、セグメンテーション違反が発生します。

于 2013-08-22T19:12:14.970 に答える
1

「こんにちは」は文字列定数です。constantの定義により、記述されることを意図したものではありません。

最初の例では、「t」はポインターであり、いずれかの文字列定数を指す (割り当てる) ことができます。

于 2013-08-22T19:10:37.347 に答える