-1

The error that I'm struggling, with some examples

I have written a code for finding prime numbers using sieve of Eratosthenes algorithm, but the problem is my code works as it tends to be, but it shows an unspecified or undefined error for some numbers. It shows like "entering initial value (n) infinite times" as the error and for some numbers, I mentioned in the image, it works perfectly. As I started recently studying C in-depth I couldn't find what is going wrong. I request the code-ies to help me in this case, and also help me realize what is the mistake, why it happens and how to prevent it.

Edit: Actually it gets into error zone for smaller numbers, and as the number grows, it works fine and gets again into errors for some, like in the image specified.

Here's the code (modified to avoid garbage values):

#include <stdio.h>
int main()
{
    int n;
    printf("enter number: ");
    scanf("%d",&n);
    int arr[n],pr=2;
    for(int i=0;pr<=n;i++)
    {
        arr[i]=pr;
        pr++;
    }
    int j,k=0;
    while(arr[k]<=n)
    {
        for(j=2;j<n;j++)
        {
            for(k=0;k<n;k++)
            {
                if(arr[k]%j==0 && arr[k]>j)
                    arr[k]=0;
            }
        }
    }
    for(int i=0;i<n;i++)
    {
        if(arr[i]>0)
            printf(" %d",arr[i]);
    }
    printf("\n");
    return 0;
}
8
  • 1
    Two possible problems: 1) You need to check that n is not too big, to overflow the stack; 2) You loop initializing arr, are you sure it will initialize all elements of arr? And that it will not go out of bounds of arr? Commented Mar 30, 2024 at 12:51
  • 1
    Oh, and with while(arr[k]<=n) you use k uninitialized. Which means it will have an indeterminate value (which may not be zero). You also use k for more than one thing. And if the initial indeterminate value of k is non-negative, it will go out of bounds. Commented Mar 30, 2024 at 12:52
  • I've checked those and nothing happens after modification, yet some garbage values has been controlled, that was my mistake Commented Mar 30, 2024 at 14:39
  • for(i=0;pr<=n;i++) { arr[i]=pr; is one-too-many: use for(i=0;pr<n; i++) Commented Mar 30, 2024 at 14:39
  • but that omits the (n-1)th element value, i mean, if my number given is 307, eventhough it is a prime, it won't be printed, as the value ends with 306, and I can't get through the error Commented Mar 30, 2024 at 14:50

1 Answer 1

1

There appears to be a mismatch with regard to the number of elements in the array and how the elements of the array are being accessed.

Rather than loading the array with numbers it's simpler to just use the index number of each element of the array to represent each number. Then store either a true or false value -- a flag indicating whether the number represented is or is not prime -- in each array element. That is, for example, if arr[5] held a value of 1 (true) then it represents that the number 5 is considered prime.

Also when using a for loop it's a good idea to have all three of the loop's expressions use the same variable. Your first for loop uses i first. Then pr and n. The loop then uses i again. It's usually better, especially at first, to have a single variable control all three parts of a for loop.

/* Sieve of Eratosthenes.c
   standard implementation without the usual optimizations
*/

#include <stdio.h>

int main(void)
{
    printf("enter number (limit): ");
    int n;
    scanf("%d", &n);

    int arr[n + 1];                   // n + 1 to include array element 0
    for (int i = 2; i <= n; ++i) {    // skip array elements 0 and 1
        arr[i] = 1;                   // mark elements 2 to n as true (prime)
    } 

    for (int i = 2; i <= n; ++i) {    // skip array elements 0 and 1
        if (arr[i]) {                 // if true (prime)
            for (int j = i + i; j <= n; j += i) {  // cross off multiples
                arr[j] = 0;           // mark element as false (not prime)
            }
        }
    }

    printf("primes:");
    for (int i = 2; i <= n; ++i) {    // skip array elements 0 and 1
        if (arr[i]) {                 // if true (prime)
            printf(" %d", i);         //     print array element number  
        }
    }
    printf("\n");

    return 0;
}
Sign up to request clarification or add additional context in comments.

2 Comments

UV for simplicity and adherence to algorithm (no optimisations.) Suggest int arr[1 + n]; would (perhaps) more clearly express "accounting for zero". Also, checking scanf() return code and enforcing reasonable upper bound of array that will eat up stack. (Note: a one-byte char flag, instead of four-byte int, would allow much larger maximum values and still fit on the default stack.)
This code works fine and simpler than mine in terms of logical complexity, thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.