3

私はこの質問が尋ねられたことを知っています.プログラムを修正できませんでした.

  void swap1(char*str1,char*str2)
{
    char *ezer =new char[strlen(str1)];
    for (int i = 0 ; i <= strlen(str1);i++)
        ezer[i]=str1[i];
    delete [] str1;
    str1= new char[strlen(str2)];
    for (int i = 0 ; i <= strlen(str2);i++)
        str1[i]=str2[i];
    delete [] str2;
    str2= new char[strlen(ezer)];
    for (int i = 0 ; i <= strlen(ezer);i++)
        str2[i]=ezer[i];
    delete[] ezer;
}

1回目は2回目(他の値で)の作業バットで、エラーが発生しますエラーは最後の行で発生しましたdelete[] ezer;なぜ削除できないのezerですか?

エラー:

heap corruption detected after normal block (#174) at 0x007D7A48
CRT detected that the application wrote to memory end of heap buffer
4

2 に答える 2

5

strlen は、文字列の末尾にあるヌル ターミネータをカウントしません。つまり、swap 関数を 1 回適用すると、2 つの文字列が交換されますが、null で終了することはなくなります。null ターミネータのない文字列に対する strlen の動作は未定義です。つまり、これらの解体された文字列の 1 つをトラバースすると、割り当てられたヒープの範囲外で実行されます。

C の文字列は、文字列の末尾を示すゼロ値のバイトを持つ文字ポインターとして表されます (前述のヌル ターミネーター)。「文字列」を操作するライブラリ ルーチンは、最後が null でマークされた文字配列が提供されることを期待しており、それ以外の場合は未定義の動作をします (その時点で文字列ではなく char 配列を提供するため)。

独自に作成する代わりに、ライブラリ関数 strcpy を使用してください。

詳細については、この質問を参照してください。

于 2013-03-01T07:31:15.127 に答える
0

ここで 0 ターミネータにスペースを割り当てることができません:

char *ezer = new char[strlen(str1)];

これを次のように変更します。

char *ezer = new char[strlen(str1) + 1];

実際の (最初の) メモリ破損は次の場所で発生します。

  for (int i = 0 ; i <= strlen(str1);i++)
    ezer[i]=str1[i];

最後の繰り返し (0 ターミネータをコピーするもの) とezer[i]同様に、 に割り当てられたメモリの「すぐ後ろ」を参照しezerます。

文字配列 c の他の 2 つの割り当てについても同じことをやり直します。

とにかく、これはヒープの破損を修正するため、関数は期待どおりに動作しません。でもこれはまた別の話…ですね。;-)

于 2013-03-01T07:57:02.800 に答える