0

マージソートを使用して配列をソートする関数を作成しています。これまでのところ、私は2つの機能を持っています:

template <typename Item, typename SizeType>
void merge_sort(Item data[], SizeType size) {
SizeType size1, size2;
if(size > 1) {
    size1 = size/2;
    size2 = size - size1;
    merge_sort(data,size1);
    merge_sort((data+size1),size2);

    merge(data,size1,size2);
}
}

と:

template <typename Item, typename SizeType>
void merge(Item data[], SizeType size1, SizeType size2) {
Item* temp;
SizeType copied = 0;
SizeType copied1 = 0;
SizeType copied2 = 0;

temp = new Item[size1 + size2];

while(copied1 < size1 && copied2 < size2) {
    if(data[copied1] < (data + size1)[copied2])
        temp[++copied] = data[++copied1];
    else
        temp[++copied] = (data + size1)[++copied2];
}

while (copied1 < size1)
    temp[++copied] = data[++copied1];
while (copied2 < size2)
    temp[++copied] = (data + size1)[++copied2];

for(SizeType i = 0; i < size1 + size2; ++i)
    data[i] = temp[i];
delete [] temp;
}

しかし、プログラムを実行しようとすると、通常のブロックの後にヒープが破損し、ヒープ バッファーの終了後にアプリケーションがメモリに書き込んだことを CRT が検出したというデバッグ エラーが表示されます。これが何を意味し、どのように修正できるかを誰かが説明できますか?

4

3 に答える 3

2

値を使用する前にインクリメントしています...そのため、基本的にチェックは廃止されます...

代わりに使用copied++します。

使用する前にインクリメントすると範囲外になるため、ポストインクリメント演算子が必要です。 インクリメントおよびデクリメント演算子

于 2012-12-06T19:34:43.897 に答える
2

インクリメントがプリインクリメントではなくポストインクリメントであるということですか? 例えば:

    temp[copied++] = (data + size1)[copied2++];

プレインクリメントを使用すると、最初の反復で が であったときcopied20、 にアクセスしてい(data + size1)[1]ました。割り当てられたメモリの最後にcopied2到達すると、最後を超えてアクセスしています。

これを避けるために、インクリメントを部分式として使用しないことをお勧めします。書くのも読むのも混乱するかもしれません。

于 2012-12-06T19:37:09.803 に答える
1

コピーされた = 0 およびコピーされた 1 = 0 の場合、行

temp[++コピー済み] = データ[++コピー済み1];

生産します

temp[1] = データ[1];

ここでは接頭辞 ++ が最も優先度が高いため

于 2012-12-06T19:42:23.867 に答える