问:使用Sieve of Eratosthene查找两个给定数字a和b之间的所有素数。
我使用动态数组存储素数,但它确实无效。
调试之后,一切都很好,直到最后
printf()
崩溃了。
代码
int main() {
int i, j, n, a, b, k;
int *tab;
scanf("%i", &n); // n is number of sets
for (i = 1; i <= n; i++){
scanf("%i %i", &a, &b);
tab = (int*) malloc(b * sizeof(int)); //allocating the memorry
for (j= 0; j < b; j++){ //seting all numbers to be prime
*(tab + j) = 1;
}
for (j = 2; j <= b; j++){
if (*(tab + j) == 1){
for(k = j; k <= b; k+=j)
*(tab + k) = 0; //seting 0 for all non prime numbers
}
}
for (j = a; j <= b; j++){
if (*(tab + j) == 1){
printf("%i", j); //printing prime numbers
}
}
free(tab);
}
return 0;
}
答案 0 :(得分:0)
你的第二个循环应该是
for (j = 2; j <= b; j++){
if (*(tab + j) == 1){
for(k = j; k <= b; k += j)
*(tab + k) = 0; //seting 0 for all non prime numbers
}
}
问题是因为你使用了乘法,你试图访问选项卡数组中的索引高于其分配大小的项目。
编辑:正如@melpomene所说,数组太短了。因此分配应该是
tab = (int*) malloc((1+b) * sizeof(int));
答案 1 :(得分:0)
问题是,您正在从其边界访问数组:
*(tab + k*j) = 0;
当
k <= b
j <= b
声明 b 元素的数组时,只能访问0到b-1索引的数组。
BTW,正如评论中所提到的,使用tab[k*j]
更具可读性,并清楚地表明tab是数组。
我真的不明白你的集数是什么意思,但从wiki取得的Eratosthenes的Sieve的伪代码从2应用到 n 。因此,在您的情况下,2变为 a , n 变为 b 。您不需要检查从 a 到 b 的所有数字, b 的根目录就足够了。 您的算法应如下所示:
b - a
元素的数组