2015-05-25 80 views
-1

我是一个初学者,但我不会问这个问题,如果我没有花费几个小时。运行时错误代码(C++)

该代码是关于以最有效的方式在两个数字之间找到素数,其中最大限制为10^9。

下面的代码给我运行时错误,但我不知道为什么...帮助

#include <iostream> 
#include <stdio.h> 
#include <math.h> 
using namespace std; 

long int prime[32000]; 

bool isprime(long int a){ 
    for(long int i = 3; i <= 32000; i+=2){ 
     if(a%i == 0){ 
      return false; 
     } 
    } 
    return true; 
} 

void generateprimes(){ 
    long int a = 0; 
    for(long int i = 3; i < 31623 ; i+=2){ 
     if(isprime(i)){ 
      prime[a] = i; 
      a++; 
     } 
    } 
} 

bool newisprime(long int a){ 
    long int x =0; 
    for(long int i = prime[x]; i <= sqrt(a); i = prime[++x]){ 
     if(a%i == 0){ 
      return false; 
     } 
    } 
    return true; 
} 

void generateprimes_inbetween(long int n,long int m){ 
    if(n%2 == 0){ 
     ++n; 
    } 
    if(n == 1){ 
     printf("2\n"); 
     n = 3; 
    } 
    for(long int i = n; i <= m ; i+=2){ 
     if(newisprime(i)){ 
      printf("%d\n",i); 
     } 
    } 
} 

int main() { 
    long int a,b,c; 
    scanf("%ld",&a); 
    generateprimes(); 
    for(long int i = 0; i < a ; i++){ 
     scanf("%ld %ld",&b,&c); 
     generateprimes_inbetween(b,c); 
     printf("\n"); 
    } 
    return 0; 
} 
+3

你确实是知道数组的索引限制?由于索引基于零,所以'32000'元素的数组将具有从'0'到'31999'(含)的索引。你可能至少有一次出界。 –

+3

另外,学习使用调试器,因为如果你在调试器中运行你的程序,它将停在崩溃位置,让你检查函数调用堆栈以及相关变量的值。 –

+0

导致错误的输入是什么?通过输入随机值,我在'newisprime()','a%i'处得到了一个除以0的错误。 – emlai

回答

1

isprime()您遍历所有数字的排列prime[]英寸但在启动时,因为它是全局数据,所以它们中的大多数将为0,因此a%i将导致致命的除以0.

您有某个位置可以跟踪存储在您的素数中的数字数组并仅对您存储在其中的素数进行测试。

假设它的功课,你不允许使用载体,可以按如下方式做到这一点:

const size_t max_primes = 32000;  // avoid hard coded values 
unsigned long prime[max_primes] {2, 3}; // prefilled values 
size_t nprimes = 2;      // number of primes in the array 

bool isprime(unsigned long a){ 
    for(size_t i = 0; i < nprimes; i++){ 
     if(a%prime[i] == 0) 
      return false; 
    } 
    return true; 
} 
void generateprimes(){ 
    nprimes = 2; 
    for(unsigned long i = 3; nprimes<max_primes && i < ULONG_MAX; i += 2){ 
     if(isprime(i)){ 
      prime[nprimes] = i; 
      nprimes++; 
     } 
    } 
} 
bool newisprime(unsigned long a){ 
    size_t x = 0; 
    for(unsigned long i = prime[x]; i <= sqrt(a) && x<nprimes; i = prime[++x]){ 
     if(a%i == 0) 
      return false; 
    } 
    if(x == nprimes) { 
     cout << "Attention: Reaching end of prime table !!" << endl; 
    } 
    return true; 
} 

一些言论:

  • 的指数,它的安全使用无符号类型size_t
  • 确保每次使用一个索引,它仍然是边界
  • 如您正数的工作中,它可能是有意义的使用unsigned long