如何使用动态数组?

时间:2017-10-22 22:02:22

标签: c

:使用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;
}

2 个答案:

答案 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 的根目录就足够了。 您的算法应如下所示:

  1. 创建用于保存b - a元素的数组
  2. 使每个元素等于1
  3. 制作符合复数的Eratosthenes规则的0个元素
  4. 打印包含1的索引。