我正在尝试制作一个程序,使用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;
}
答案 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_t
(unsigned long int
在我的系统上)的范围是42亿。如果这样可以满足您的要求,请将int
定义更改为unsigned
,注意您的循环控件不会换行,即使用unsigned x = UINT_MAX - 1;
如果您没有5Gb可用内存,请使用@BoPersson建议的位状态。
答案 1 :(得分:0)
以下代码检查错误,使用高达5000000000的值进行测试,正确输出素数的最终计数,使用malloc以避免超出可用的堆栈空间。
CounterSamples