好吧,所以,为了好玩,我正在研究eratosthenes的筛子。 它工作得很好,所以我试图提高它的运行时复杂性。而现在,我不知道为什么,但我是一个分段错误。 这是代码:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int* check = malloc(1000000000 * sizeof(int));
long long int i;
for(i = 0;i < 1000000000;i++)
{
check[i] = 0;
}
int j = 0;
for(i = 2;i <= 1000000002;i++)
{
if(check[i] == 0)
{
printf("%lld\n", i);
for(j = 1;j < (1000000001/i);j++)
{
check[j*i] == 1;
}
}
}
return 0;
}
任何有关失败原因的帮助都将不胜感激。
答案 0 :(得分:0)
您的代码有多个错误,其中任何错误都可以解释段错误。首先,您尚未检查malloc
的返回值,即使您完全确定它不是NULL
,也可能是i
。
其次,当你将Initial allocation: 1,000,000,000
Range of i: 2 to 1,000,000,002 inclusive
从2迭代到1000000002时,你超出了你分配的数组的范围。有这么多的零,很难看出来,所以这里有你的数字用分隔符:
{{1}}
在该循环结束时,您将访问数组末尾的内存。
答案 1 :(得分:0)
#include <stdio.h>
#include <stdlib.h>
#if 1
static const size_t N = 1000 * 1000 * 1000;
#else
static const size_t N = 1000;
#endif
不要使用幻数,将其定义为常量。 1000000000也难以阅读。您的C编译器可以在发出可执行文件之前为您进行计算。而且你应该从一小部分开始。如果您将#if 1
更改为#if 0
,那么将#else
定义为1,000的N
子句将生效。
int main(void)
{
char* check = malloc(N + 3);
当您基本上使用check
作为布尔数组时,它不必是int
类型。 int
占用4个字节,而char
仅占1个字节。
if (NULL == check) {
perror("malloc");
abort();
}
malloc
在找不到指定长度的内存块时无声地返回NULL
。但是如果你使用64位操作系统和编译器,我认为它不会失败......
long long int i;
memset(check, 0, sizeof(check[0]) * (N + 3));
memset
使用第二个参数的值填充数组(此处为0
。)第三个参数采用输入数组的BYTES数,因此我使用了sizeof(check[0])
(这个对于char
数组而言,sizeof(char)==1
不是必需的,但我始终坚持这种做法。)
int j = 0;
for(i = 2;i <= N+2;i++)
{
if(check[i] == 0)
{
printf("%lld\n", i);
for(j = 1;j < ((N+1)/i);j++)
{
check[j*i] = 1;
你写了check[j*i] == 1
,但这是一个相等的测试,其结果没有任何影响。
}
}
}
free(check);
最好始终free
使用malloc
分配的内存块,无论是否需要free
(在这种情况下不是,因为您的程序刚刚退出)在筛子计算结束时。)也许直到你真正流利的C。
return 0;
}