如何阻止数组在c中被覆盖?

时间:2018-09-24 20:21:49

标签: c arrays memory

我正在尝试在C中构建素筛,这样做时,我遇到了0除法错误。这对我来说很奇怪,因为我要除以质数(当然不能为0)。

我设法将问题追溯到以下代码段(注意顶部和底部调试打印):

int *comb(int primes[], int start, int end) {
    for (int i = 1;i<primes[0];i++) {
        printf("primes[%d] = %d\n", i, primes[i]);
    }

    // Initialize check-list
    int *numbers = malloc(sizeof(int)*(end - start));
    for (int i = start;i < end;i++) {
        numbers[i - start] = i;
    }

    for (int i = 1;i<primes[0];i++) {
        printf("primes[%d] = %d\n", i, primes[i]);
    }
}

当然,打印语句应该给出完全相同的输出,但是从primes[10]开始,它们是完全不同的。实际上,此列表应包含从0到100的所有素数,现在它给出输出:

primes[1] = 2
primes[2] = 3
primes[3] = 5
primes[4] = 7
primes[5] = 11
primes[6] = 13
primes[7] = 17
primes[8] = 19
primes[9] = 23
primes[10] = 39617
primes[11] = 0
primes[12] = 100
primes[13] = 101
primes[14] = 102
primes[15] = 103
primes[16] = 104
primes[17] = 105
primes[18] = 106
primes[19] = 107
primes[20] = 108
primes[21] = 109
primes[22] = 110
primes[23] = 111
primes[24] = 112
primes[25] = 113

对我来说很明显,这意味着我的numbers[]数组正在以某种方式覆盖我的primes[]数组。

什么可能导致这种奇怪的行为,我该如何阻止它发生?

编辑:我设法解决此问题的最小示例是:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>

int *Sieve(int n) {
    int found_primes = 0;

    // Initialize prime array
    int *prime = malloc(sizeof(int) * n);
    for (int i = 0;i < n;i++) {
        prime[i] = i;
    }

    // Start sieving
    for (int i = 2;i < n;i++) {
        // If i isn't sieved out, print it and discard its multiples
        if (prime[i] != 0) {
            found_primes++;
            for (int j = 2 * i;j < n;j += i) { // Discard multiples.
                prime[j] = 0;
            }
        }
    }
    printf("We found %d primes in step 1:\n", found_primes);
    int *prime_list = malloc(found_primes + 1);
    prime_list[0] = found_primes + 1; // Add length information to array.

                                      // Fill prime_list
    int counter = 1; // Skip length element
    for (int i = 2;i < n;i++) {
        if (prime[i] != 0) {
            prime_list[counter++] = prime[i];
        }
    }

    return prime_list;
}

int *comb(int primes[], int start, int end) {
    for (int i = 1;i<primes[0];i++) {
        printf("primes[%d] = %d\n", i, primes[i]);
    }

    // Initialize check-list
    int *numbers = malloc(sizeof(int)*(end - start));
    for (int i = start;i < end;i++) {
        numbers[i - start] = i;
    }

    for (int i = 1;i<primes[0];i++) {
        printf("primes[%d] = %d\n", i, primes[i]);
    }

    // Comb out the non-primes
    for (int i = 1;i < primes[0];i++) {
        // x*primes[i] - start --> needs to be positive
        printf("Start: %d\n primes[%d]: %d\n", start, i, primes[i]);
        double j_start = ceil(start / primes[i]) * primes[i];
        for (int j = j_start; j < end;j += primes[i]) {
            numbers[j - start] = 0;
        }
    }

    // Count primes
    int found_primes = 0;
    for (int i = 0;i < end - start;i++) {
        if (numbers[i] != 0) {
            found_primes++;
        }
    }
    printf("We found %d primes in step 2.\n", found_primes);

    // Fill prime_list
    int *prime_list = malloc(found_primes + 1);
    prime_list[0] = found_primes + 1; // Add length information to array.

    int counter = 1; // Skip length information
    for (int i = 0;i < end - start;i++) {
        if (numbers[i] != 0) {
            prime_list[counter++] = numbers[i];
        }
    }

    return prime_list;
}

int main() {
        // Initialize program with user input
        int max_number = 10000;

        // Calculate all needed prime numbers.
        int sqrtn = floor(sqrt(max_number));
        int *prime_list = Sieve(sqrtn+1);

        int *primes = comb(prime_list, sqrtn, max_number);
    return 0;
}

0 个答案:

没有答案