-4

このコードにより、Visual Studio 2010 に対応するヒープが破損します。ヒープが破損する原因は何ですか? このコードのどの部分が原因ですか?

#define size 65536
int main()
{
    int* a =  new int[size];//size is equal to
    srand(time(NULL));
    for(int i = 0 ; i < size; i++)
    {
        a[i]= 1 + rand() % 10;
    }

    for(int i = 0;  (size / 2) / pow((double)2, i)>= 1; i++)
    {
        int n = pow((double)2, i);
        int offset = 0;
        for(int j = 0; j < (size / 2) / pow((double)2, i); j++)
        {
            int* tmp = new int[n];
            merge(a + offset, n, a + offset + n, n, tmp);
            memcpy(a + offset, tmp, n*2 * sizeof(int));
            offset += pow((double)2, i+1);
        }
    }

    for(int i = 0; i < size; i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<endl;
    system("PAUSE");
    return 0;
}
4

3 に答える 3

3

memcpy に問題があると思われます。tmp から (n * 2 * sizeof(int)) バイトをコピーしていますが、n * sizeof(int) しか割り当てていません。

于 2012-04-29T16:36:33.690 に答える
1

ヒープの破損は、メモリのブロックを割り当ててから、そのブロックの外側にデータを書き込んだことを意味します。通常、これは配列の末尾を超えて書き込んだことを意味します。

少量の上書きは、メモリ割り当ての後に配置される「ガード ワード」にヒットするため、プログラムが正常に実行されている間、ランタイムは bd レポート ヒープの破損を検出します。ただし、さらに書き込むと、他の重要なデータが壊れたり (プログラムがデータを使用しようとしたときに未定義の結果が生じる)、メモリ マップの最後まで実行されて致命的なアクセス違反エラーが発生する可能性があります。

配列へのインデックスが常に範囲 0..Length-1 であることを確認してください

使用される最大インデックスを計算できない場合は、インデックスがこの範囲内にあることを確認するコード行を挿入し、そうでない場合はデバッガーを中断します。つまり、merge/memcpy に渡す値が常に範囲内にあることを確認してください。(おそらく、1 つの要素を書きすぎている可能性があります。これに対する手っ取り早い方法は、「必要な」よりも少し多くのメモリを割り当てることですが、それは明らかに正しい解決策ではありません。意図したデータだけを書き込むようにする必要があります。に)

于 2012-04-29T16:37:40.903 に答える
1

に十分なスペースが割り当てられていませんtmp:

int* tmp = new int[2*n];

マージコードのインクリメントfor (..; ...; c_i++) も非常に疑わしいようです。

バグがいくつかある可能性があります。デバッガを使用するか、トレース メッセージを書き込んで、何が起こっているかを確認してください。範囲外に書き込んでいないことを確認してください。

于 2012-04-29T16:38:05.693 に答える