0

重複の可能性:
C 文字列の変更: アクセス違反

int main()
    {   
        char str_1[7] = "string";
        char* str_2 = new char[7];
        str_2 = "string";
        str_1[2] = 'a'; //ok
        str_2[2] = 'a'; //error

        return 0;
    }

ここで「アクセス違反」エラーが発生します ここstr_2[2] = 'a'; でインデックスを介して動的文字列にアクセスできない理由がわかりませんか? (VS2010) ありがとう。

4

4 に答える 4

3

メモリを割り当てます

char* str_2 = new char[7];

以前の割り当てを無視し(そしてメモリリークを引き起こし)、不変の文字列リテラルstr_2を指し示します:

str_2 = "string";

str_2これで、実際にはを指すようになります。const char[]暗黙のキャストchar*は、下位互換性のためだけにあります。実際、それは読み取り専用メモリを指しています。

于 2013-01-31T10:27:44.447 に答える
3

あなたのように文字列に割り当てることはできません。文字列の内容をコピーする代わりに、ポインタをコピーします。したがってstr_2、文字列リテラルを指すようになり、変更できなくなりました。文字列の内容をコピーするには、を使用しますstrcpy

str_2さらに悪いことに、あなたのバージョンのコードでは、を呼び出す行に割り当てられたメモリのメモリリークがありますnew

于 2013-01-31T10:28:12.990 に答える
3

あなたの場合は文字列リテラルを変更しようとしているので、代わりにとstr_2 = "string";書いてください。strcpy(str_2, "string")

于 2013-01-31T10:27:28.193 に答える
1

問題は、メモリセルの「ハードコピー」をどこにも行わず、ポインターを別の場所を指すように変更するだけであることです。文字列は配列であるため、strcpy または memcpy 関数を使用してコピーする必要があります。

char* str_2 = new char[7];動的メモリを割り当てます。str_2 = "string";ポインター str_2 が、割り当てられた動的メモリを指していたことを忘れて、完全に異なるメモリ セルを指すようにします。そのメモリへの参照が残っていないので、メモリ リークのバグがわかります。

str_2現在、読み取り専用メモリに存在する定数文字列リテラル「string」を 指しています。str_2[2] = 'a';これは未定義の動作であり、クラッシュが発生します。

str_1 ケースが機能する理由を理解するには、プログラミングの概念initializationassignを理解することが重要です。「str_1」のケースは、7 バイトを割り当ててから、それらのバイトを「文字列」を含むように初期化するため機能します。変数の初期化では=、実際の文字列リテラル "string" が存在する読み取り専用メモリから、str_1 が割り当てられている RAM のスタックにハード コピーが作成される唯一の場所です。

于 2013-01-31T10:37:44.777 に答える