在这里,我想找到200万以下的所有素数之和。 我使用Eratosthenes筛子,所以我需要200万个阵列。
起初,我只将数组声明为全局变量,但是zsh给我一个分段错误。所以我尝试了malloc,但错误仍然存在。 我已经测试了小型数组,程序运行正常。
此外,我使用clang-1000.10.44.2,使用-O2程序可以运行,但答案不正确。代码如下。
#include <stdio.h>
#include <stdlib.h>
#define MAXN 2000000
unsigned long long sum;
void erat(int maxn, char *flag)
{
flag[0] = 0;
flag[1] = 0;
for(int i = 2; i < maxn; i++)
if(flag[i])
for(int j = i * i; j < maxn; j+=i)
flag[j] = 0;
}
int main()
{
int i;
char *flag = (char*) malloc(MAXN * sizeof(char));
for(i = 0; i < MAXN; i++)
flag[i] = 1;
erat(MAXN, flag);
for(i = 0; i < MAXN; i++)
if(flag[i]) sum+=i;
printf("%llu\n", sum);
return 0;
}
希望有人可以帮助我,谢谢您的宝贵时间!
答案 0 :(得分:5)
当i
为46349
时,i*i
为2148229801
,这比整数更合适,因此溢出到-2146737495
,因为它小于maxn
,flag[j] = 0
被执行,超出了数组的范围,因此崩溃。
将j
更改为long long
可修复该错误:
for (long long j = (long long)i * i; j < maxn; j += i)
答案 1 :(得分:1)
您的int
在这里溢出了:
for (int j = i * i; j < maxn; j+=i)
由于i
达到2000000,所以i*i
可能大于2 31 ,从而导致溢出和undefined behavior。
您可以在外部循环中解决此问题:
for(int i = 2; i < maxn; i++)
您只需要检查maxn
的平方根,因此将其更改为:
for(int i = 2; i * i < maxn; i++)