0

ヒープ上の値の配列をスクランブルする C の簡単なテスト プログラムがあります。補足: ここのランダム ロジックには、「変位」値が を超えることを許可しない欠陥があることは知っていますがRAND_MAX、それはこの投稿のポイントではありません。

ポイントは、N = 10000 でコードを実行すると、ごくわずかな情報で時々クラッシュすることです (スクリーンショットは以下に掲載)。MinGW コンパイラを使用しています。より低いまたはより高い N 値 (たとえば、1000 または 100000) でクラッシュを再現できないようです。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

const int N = 10000;

int main() {
    int i, rand1, rand2, temp, *values;

    /* allocate values on heap and initialize */
    values = malloc(N * sizeof(int));
    for (i = 0; i < N; i++) {
        values[i] = i + 1;
    }

    /* scramble */
    srand(time(NULL));
    for (i = 0; i < N/10; i++) {
        rand1 = (int)(N*((double)rand()/(double)RAND_MAX));
        rand2 = (int)(N*((double)rand()/(double)RAND_MAX));
        temp = values[rand1];
        values[rand1] = values[rand2];
        values[rand2] = temp;
    }


    int displaced = 0;
    for (i = 0; i < N; i++) {
        if (values[i] != (i+1)) {
            displaced++;
        }
    }
    printf("%d numbers out of order\n", displaced);

    free(values);
    return 0;
}

ここに画像の説明を入力

4

1 に答える 1

3

これは、0 から RAND_MAX までの乱数を生成するためrand()配列の境界を超える N になる可能性があるためです。ただし、それが配列のサイズによって異なる理由はわかりません(ただし、時々クラッシュする理由は説明しています)。(int)(N*((double)rand()/(double)RAND_MAX))

試してください/(1+(double)RAND_MAX)(RAND_MAXの値に応じて、オーバーフローを避けるために、加算はdoubleにあることに注意してください)(関係するタイプによっては、常に機能するとは確信していませんが、Nをテストして再試行する方が安全です) )。

また、 Windows に代わる優れた Valgrind はありますか?のツールの使用方法を学びます。- この種のことを簡単に修正できます (プログラムを実行したときに何が問題だったかを正確に教えてくれます)。

于 2012-05-24T21:38:48.693 に答える