我的代码中的分段错误

时间:2011-01-30 06:37:11

标签: c algorithm primes sieve-of-eratosthenes

这是我在球形在线评判中提交的用于生成素数的代码,但我遇到了分段错误。目标是在给定范围m到n(n> m)之间generate prime numbers。这是使用Sieve of Eratosthenes算法实现的。请告诉我哪里出错了。谢谢:)

#include <stdio.h>
#include <math.h>

int main(){
    long int m,n,c1,c2,c3;
    int t;

    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&m,&n);


        //create prime list
        short int *prime;
        prime = (short int*)malloc((n-m)*sizeof(short int));

        //fill list with 0 - prime
        for(c1 = 2; c1 <= n; c1++){
                prime[c1] = 1;
        }

        //set 1 and 0 as not prime
        prime[0]=0;
        prime[1]=0;

        //find primes then eliminate their multiples (0 = prime, 1 = composite)
        for(c2 = 2;c2 <= (int)sqrt(n)+1;c2++){
            if(prime[c2]){
                c1=c2;
                for(c3 = 2*c1;c3 <= n; c3 = c3+c1){
                    prime[c3] = 0;
                }
            }
        }

        //print primes
        for(c1 = m; c1 <=n; c1++){
            if(prime[c1]) printf("%d\n",c1);
        }
    }       
    return 0;
}

4 个答案:

答案 0 :(得分:3)

c3可以在最里面的循环中达到n,但您只能在数组中分配少于n个插槽。实际上,即使您分配了n个插槽,索引n也会比您分配的插槽数多一个。在最坏的情况下,你只是破坏了一些超出数组末尾的内存,并希望不会丢弃堆栈。充其量,我想你会得到一个段错误。您可能希望将X <= n更改为X < n或在阵列中再分配一个元素。实际上,您可能应该为您的数组分配(n + 1) * sizeof(short)个字节。

此外,您永远不会设置t,您永远不会验证用户输入。如果这是针对输入有限制的竞争,后者可能没问题。此外,您永远不会释放prime数组,因此您有内存泄漏。

答案 1 :(得分:1)

当然你会分配一个(n-m)&amp;的存储器。你正在进行中 prime [n],

答案 2 :(得分:0)

当素数只有1个元素时,可能想要避免这种情况:

//set 1 and 0 as not prime
        prime[0]=0;
        prime[1]=0;

答案 3 :(得分:0)

你是malloc(n-m),但是在下面的循环中你初始化prime [2..n]。 n-m 最多为1E5,但 n 本身可能是1E9(这是一个相当大的数字)。您的简单想法可能无法实现,因为malloc(1E9)可能会失败。你需要一个更智能的算法。