Home > front end >  Why does a printf statement in a for loop seem to depend on an unrelated previous printf outside tha
Why does a printf statement in a for loop seem to depend on an unrelated previous printf outside tha

Time:03-28

I was playing around in C to implement the "sieve of Eratosthenes" for finding primes. I came up with the following code:

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

void strike_multiples(int n, int *storage); // Function prototype
int ceiling = 500;  // Maximum integer up to which primes are found

int main(void) {
    int *ptr = malloc(sizeof(int) * ceiling);  // Create buffer in memory
    int no_of_primes_found = 0;
    printf("Print anything\n");
    for (int i = 0; i < ceiling; i  ) {  // Initialise all elements in buffer to zero
        *(ptr   i * sizeof(int)) = 0;
    }

    for (int j = 2; j < (ceiling / 2)   1; j  ) {
        if (*(ptr   j * sizeof(int)) == 0) {
            strike_multiples(j, ptr);
        }
    }

    for (int k = 2; k < ceiling; k  ) {
        if (*(ptr   sizeof(int) * k) == 0) {
            no_of_primes_found  ;
            printf("%i\n", k);
        }
    }

    printf("%i primes found\n", no_of_primes_found);

    free(ptr);
    return 0;
}


void strike_multiples(int n, int *storage) {  // This function strikes all multiples of a given integer within the range
    for (int i = 2; i < (ceiling / n)   1; i  ) {   // (striking means setting the value of the corresponding index in the allocated memory to one)
        *(storage   sizeof(int) * n * i) = 1;
    }
}

This compiles fine and will, indeed, give me primes up to 500 (the last of which is 499). But the wird thing about this is the line printf("Print anything\n");. It doesn't seem to be doing anything that's relevant for functionality. But if I delete this line, or comment it out, I'm not getting any output. It seems that the printf("%i\n", k); line inside the third for loop is dependent on some other printing taking place earlier.

What is going on here? How come that doing some - any - printing before the for loop makes a difference for the entirely unrelated printing of an identrified prime in the loop?

CodePudding user response:

Such expressions in for loops in your program like this

*(ptr   i * sizeof(int)) = 0;

are incorrect and lead to undefined behavior.

Instead you need to write

*(ptr   i) = 0;

This expression is equivalent to

ptr[i] = 0;

From the C Standard (6.5.2.1 Array subscripting)

2 A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1) (E2))). Because of the conversion rules that apply to the binary operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (counting from zero).

  • Related