2014-12-09 3 views
-1

Я пытаюсь решить проблему PRIME1 SPOJ, используя Sieve of Eratosthenes. Код отлично работает для более низких чисел, но показывает следующее сообщение об ошибке для длинных Интсов -Невозможно устранить эту ошибку «Нарушение доступа»

«Необработанного исключение в 0x770d15ee в spoj1.exe: 0xC0000005: нарушение прав доступа место для записи 0x0014010c.»

Пожалуйста, помогите мне решить проблему. Также я новичок в кодировании, поэтому, пожалуйста, примите любые ошибки, которые я сделал.

Вот мой код -

#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

Да. k = k + arr[i] создавал ошибку. Спасибо. Но я все еще получаю ошибку для больших чисел. Пример - код работает нормально для m = 100000000 и n = 110000000, но отображается следующая ошибка для m = 999899999 и n = 999999999. Ошибка: «Необработанное исключение в 0x778a15ee в spoj1.exe: 0xC0000005: место записи нарушения доступа 0x00000000». Изменен код -

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

Я думаю, проблема в этой строке 'k = k + arr [i];' – Himanshu

+1

в 'calloc()', что, если 'n <= 1'? Кроме того, вы проверяли успех? –

+1

Запустите свой код под отладчиком. –

ответ

0

В этом блоке кода:

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[] 
     } 
    } 
} 

внутренняя for петля может выходить за рамки arr[]. Это происходит, когда k больше, чем n-2

+0

Да. "K = k + arr [i]" создавал ошибку. Спасибо. Но я все еще получаю ошибку для больших чисел. Пример - код работает нормально для m = 100000000 и n = 110000000, но показывает следующую ошибку для m = 999899999 и n = 999999999. Ошибка: «Необработанное исключение в 0x778a15ee в spoj1.. EXE: 0xC0000005: нарушение прав доступа месте для записи 0x00000000» Модифицированный код - для (к = обр [I] -2; к <п-1;) \t \t \t { \t \t \t \t к = к + обр [я]; \t \t \t \t, если (к <п-1) \t \t \t \t { \t \t \t \t \t обр [к] = 0; \t \t \t \t \t \t \t \t \t \t \t \t \t} – learntocode

0

Кроме того, что было получено, ваше освобождение неверно. Прежде всего, вы можете иметь утечки памяти, если итерация цикла while происходит более одного раза (обр перезаписывается новым вызовом calloc и никогда не будет освобожден). Кроме того, если цикл while имеет нулевое время, вы освобождаете указатель, который содержит мусор (поскольку он никогда не был инициализирован). Вы должны поместить вызов в free внутри цикла while (или сохранить все значения arr и произвести надлежащие проверки в конце).