C segfaults中的大型阵列,时代的Sieve

时间:2014-09-09 12:54:09

标签: c memory stack

所以,我已经有了这段代码。

void main(void){

    int n = 9999;
    int *array = calloc(n, sizeof(int));
    int i, j;

    // Populate array up to N
    for(i = 0; i < n; i++){
        array[i] = 2 + i;
    }

    // Run sievs
    sievs(array, n);

    print_prime(array, n);
}

我的问题是,如果N足够大,程序将核心转储。我的理论是在堆栈上分配了一些东西,并且它不足以容纳那么多数据,但是我使用的是calloc,所以它应该是heep。

两个打印功能看起来像这样:

void print_prime(int *a, int n){
    int i;
    for (i = 0; i < n; i++){
        if(a[i] != -1)
            printf("Prime: %d \n", a[i]);
    }
}

是否有任何此代码导致它?我不明白为什么。

这是siev功能:

void sievs(int *array, int n){

    int i, j;

    for(i = 2; i <= n; i++){
        if(array[i-2] != -1){
            for(j = i*i; j <= n; j+=i){
                array[j-2] = -1;
            }
        }
    }

}

我看不出有什么不妥,但是,我只是在计算机科学的第二年,所以我没有经历过C的经历。我试图解决这个问题一段时间。它适用于小数字。然而,不是大型的,我在互联网上阅读的所有内容都表明它可能是堆栈的问题。

这里有什么东西在这里分配?

2 个答案:

答案 0 :(得分:5)

n程序会崩溃,因为

j = i * i

将导致j变量(int类型)溢出。因此在

array[j-2] = -1;

索引j - 2将为负数。

您可以通过声明j至少long或使用任意精度库(例如the GNU Multiple Precision Arithmetic Library)来解决问题。

答案 1 :(得分:-3)

&#34; i&lt; = n&#34;和&#34; j&lt; = n&#34;偷偷溜进了&#34; sievs()&#34;功能。它们应该是&#34; i&lt; N'#34;和&#34; j&lt; N'#34;