为什么这个C程序会崩溃?

时间:2012-05-24 21:35:51

标签: c crash

我在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;
}

enter image description here

1 个答案:

答案 0 :(得分:3)

可能是因为rand()生成从0到RAND_MAX 包含的随机数,因此(int)(N*((double)rand()/(double)RAND_MAX))可以是N,超出数组边界。但是,我不明白为什么会因数组大小而异(这确实解释了为什么它有时只会崩溃)。

尝试/(1+(double)RAND_MAX)(请注意,添加到double,以避免溢出,具体取决于RAND_MAX的值)(尽管我不相信它将始终有效,具体取决于所涉及的类型。它将是更安全地测试N并再试一次。)

另外,学习使用Is there a good Valgrind substitute for Windows?中的工具 - 它们可以很容易地修复这些工具(它们会告诉您运行程序时到底出了什么问题)。