-1

I am trying to solve the PRIME1 problem of SPOJ using Sieve of Eratosthenes. The code works fine for lower integers but shows the following error for long ints -

"Unhandled exception at 0x770d15ee in spoj1.exe: 0xC0000005: Access violation writing location 0x0014010c."

Please help me to resolve it. Also I am new to coding so please bear with any mistakes I made.

Here's my code -

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

int main()
{
    int m, n, test, i, k;
    long int *arr, p;

    scanf("%d", &test);

    while (test--)
    {
        scanf("%d%d", &m, &n);

        arr = (long int *)calloc(n - 1, sizeof(long int));

        if (m == 1)
        {
            m = 2;
        }
        arr[0] = 2;

        for (i = 1; i < n - 1; i++)
        {
            arr[i] = arr[i - 1] + 1;
            // printf("%d\n",arr[i]);
        }

        for (i = 0; i < n - 1; i++)
        {
            if (arr[i] != 0)
            {
                for (k = arr[i] - 2; k < n - 1; )
                {
                    k = k + arr[i];
                    arr[k] = 0;
                }
            }
        }

        for (i = 0; i < n - 1; i++)
        {
            if (arr[i] != 0 && arr[i] >= m)
            {
                printf("%d\n", arr[i]);
            }
        }

        printf("\n");
    }

    free(arr);
    return 0;
}

EDIT

Yes. k = k + arr[i] was creating the bug. Thank you. But I am still getting an error for large numbers. Example - code runs fine for m = 100000000 and n = 110000000 but shows the following error for m = 999899999 and n = 999999999. The error is - "Unhandled exception at 0x778a15ee in spoj1.exe: 0xC0000005: Access violation writing location 0x00000000." The modified code is -

for(k = arr[i]-2; k<n-1;)
    {
        k = k + arr[i];
        if(k < n-1)
        {
            arr[k] = 0;
        }
jwpfox
  • 5,124
  • 11
  • 45
  • 42
  • 1
    I think problem is in this line `k = k + arr[i];` – Himanshu Dec 09 '14 at 05:52
  • 1
    in `calloc()`, what if `n <=1` ? also, did you check for success? – Sourav Ghosh Dec 09 '14 at 05:55
  • 1
    Run your code under a debugger. – Jonathon Reinhart Dec 09 '14 at 05:56
  • 1
    The `free` should go inside the `while` body so that it mazches the `calloc`. Otherwise, you'll allocate x times, but free only once. – M Oehm Dec 09 '14 at 06:14
  • Also, look into what Himanshu said: You increase `k` and then write to `arr[k]` without checking that it is in range. You should probably write first and increase then. The `for` condition will prevent out-of-bounds access. (You must adapt the initial value of `k`, of course.) – M Oehm Dec 09 '14 at 06:18
  • it would be very helpful if all those local variables had meaninful names and/or comments about their contents. – user3629249 Dec 09 '14 at 07:08
  • regarding the calls to scanf() 1) the returned value needs to be check to assure the format conversion(s) was successful. 2) the format strings need a leading ' ' so left over white space in stdin is consumed/skipped. 3) the scanf that is inputting two integers is not showing any delimiter (a space would work) between the numbers, so how is the program to know when one number ends and the next begins. 4) before calling scanf, printf a guide to the user as to what is expected for input. – user3629249 Dec 09 '14 at 07:12

2 Answers2

0

In this code block:

for (i = 0; i < n - 1; i++)
{
     if (arr[i] != 0)
     {
         for (k = arr[i] - 2; k < n - 1; )
         {
             k = k + arr[i];
             arr[k] = 0;  // <-- this line can/will access an element of arr[]
                          //     that is beyond the bounds of the arr[] array
                          //     remembering that arr[] only contains n-1 elements 
                          //     therefore the max offset is m-2
                          //     so, when 'k' gets to be >= n-1
                          //     then arr[k] is accessing an element 
                          //     beyond the end of arr[]
         }
     }
 }

The inner for loop can exceed the bounds of arr[]. This happens when k is greater than n-2

nchen24
  • 502
  • 2
  • 9
user3629249
  • 16,402
  • 1
  • 16
  • 17
  • Yes."k = k + arr[i]" was creating the bug. Thank you. But I am still getting an error for large numbers. Example - code runs fine for m = 100000000 and n = 110000000 but shows the following error for m = 999899999 and n = 999999999. The error is - "Unhandled exception at 0x778a15ee in spoj1.exe: 0xC0000005: Access violation writing location 0x00000000." The modified code is - for(k = arr[i]-2; k – learntocode Dec 09 '14 at 13:42
0

Additionally to what has been answered, your freeing is incorrect. First of all you can have memory leaks if the iteration of the while loop happens more than once (arr gets overwritten by a new call to calloc and will never be freed). Also, if the while loop happens zero times, then you are freeing a pointer that holds garbage (because it was never initialized). You have to put the call to free inside the while loop (or save all values of arr and make proper checks at the end).

Philipp Murry
  • 1,660
  • 9
  • 13