数组大小

时间:2015-10-25 17:32:57

标签: c primes sieve-of-eratosthenes

我正在尝试制作一个程序,使用Eratosthenes的筛子计算不超过整数的素数。虽然我的程序对于小数字工作正常(和快速),但在一定数量(46337)之后,我得到一个"命令,终止于信号11和#34;错误,我想这与数组大小有关。我试图使用malloc(),但我没有把它弄得很对。我应该为大数字(高达50亿)做些什么?

#include <stdio.h>
#include<stdlib.h>
int main(){
signed long int x,i, j, prime = 0;
scanf("%ld", &x);
int num[x];
for(i=2; i<=x;i++){
  num[i]=1;
}
for(i=2; i<=x;i++){
  if(num[i] == 1){
    for(j=i*i; j<=x; j = j + i){
      num[j] = 0;
    }
    //printf("num[%d]\n", i);
    prime++;
  }
}
 printf("%ld", prime);
 return 0;
}

2 个答案:

答案 0 :(得分:0)

你的数组

int num[x];

位于堆栈中,只能容纳小数组。对于大型阵列,您必须分配内存。您可以使用char类型来节省内存膨胀,因为您只需要一个状态。

char *num = malloc(x+1);              // allow for indexing by [x]
if(num == NULL) {
    // deal with allocation error
}

//... the sieve code

free(num);

我建议您也必须使用

检查i*i是否未超出int限制
if(num[i] == 1){
    if (x / i >= i){                  // make sure i*i won't break
        for(j=i*i; j<=x; j = j + i){
            num[j] = 0;
        }    
    }    
}    

最后,你想要达到50亿,超出uint32_tunsigned long int在我的系统上)的范围是42亿。如果这样可以满足您的要求,请将int定义更改为unsigned,注意您的循环控件不会换行,即使用unsigned x = UINT_MAX - 1;

如果您没有5Gb可用内存,请使用@BoPersson建议的位状态。

答案 1 :(得分:0)

以下代码检查错误,使用高达5000000000的值进行测试,正确输出素数的最终计数,使用malloc以避免超出可用的堆栈空间。

CounterSamples