簡體   English   中英

在我的斐波那契C ++代碼中找不到分段錯誤的原因

[英]Can't find reason for segmentation fault in my Fibonacci C++ code

我的代碼存在段錯誤。 我不明白為什么。 它可能與我制作的“ fermatPrimeTest()”函數有關。

#include <iostream>
#include <cmath>
#include <cstdlib>
#include "fib.h"
using namespace std;

bool fermatPrimeTest( unsigned long int p )
{
  if ( p % 2 == 0 ) { // if even
    return false;
  } 
  else if ( p == 1 || p == 2 || p == 3 ) { // if 1, 2, or 3
    return true;
  }
  unsigned long a = 2 ; // just give it an initial value, make it happy
  for ( int i=0 ; i < 3 ; i++) {
    if (GCD(a, p-1) != 1) {
      a = rand() % (p-1) + 1;
    }
    // cout << "a=" << a << " ,p=" << p << GCD(a, p-1) << endl;
  }
  return true;
}

int GCD(unsigned long int a, unsigned long int b) {
  while( 1 ) {
    a = a % b;
    if( a == 0 )
      return b;
      // cout << "GCD-b=" << b << ", GCD-a=" << a << endl;

    b = b % a;

    if( b == 0 )
      return a;
      // cout << "GCD-a=" << a << ", GCD-b=" << b << endl;
  }
}

// fills array with Fibonacci primes
// returns number of primes
unsigned long findFibonacciPrimes (unsigned long lowerBound,
                                   unsigned long upperBound,
                                   unsigned long result[])
{  
  int i = 0;  //counter
  unsigned long maxElements = upperBound - lowerBound + 1;  // there can be no more array elements than this

  /*
  The array result is guaranteed to have enough space to store all the numbers found. 
  Your program will crash if it attempts to write past the end of the array, and no 
  marks will be awarded for any tests in which this occurs. You are also guaranteed that 
  1 < lowerBound < upperBound < 3,000,000,000.
  Every F_n that is prime has a prime  index n, with the exception of F_4=3. 
  However, the converse is not true (i.e., not every prime index p gives a prime F_p). 
  */

  unsigned long int one = 0, two = 1, three = one + two;   // element x-2, x-1, and x for Fib sequence
  result[i++] = 0;
  result[i++] = 1;

 while ( lowerBound < three < upperBound ) {
    if ( fermatPrimeTest(three) ) {
      result[i++] = three;
    }
    one = two;
    two = three;
    three = one + two;
  }
  return sizeof result / sizeof result[0];   // return size of array TODO!
}
int main() {
  unsigned long result[100];
  findFibonacciPrimes(1,100,result);
}

第67行:

 while ( lowerBound < three < upperBound ) {

許多語言不正確地支持鏈式比較。 您需要編寫以下代碼:

 while ( lowerBound < three && three < upperBound ) {

在C ++中, lowerBound < three < upperBound解釋為(lowerBound < three) < upperBound 表達式lowerBound < three將始終導致0(false)或1(true),因此while由於upperBound為100,因此while循環將始終成功。

這導致行result[i++] = three; 由於有超過100個斐波那契素數,因此可以運行100次以上。 但尺寸result是只有100。當i ≥100中,程序將被寫入無效存儲器區域,並且這將導致段錯誤。


正如安德列斯(Andres)在評論中所說,您最好使用vector ,例如

#include <vector>
...
std::vector<unsigned long> findFibonacciPrimes(unsigned long lowerBound,
                                               unsigned long upperBound) {
   std::vector<unsigned long> result;
   result.push_back(0);
   result.push_back(1);  // note that 0 and 1 aren't primes.
   ...
   while (lowerBound < three && three < upperBound ) {
      if ( fermatPrimeTest(three) ) {
        result.push_back(three);
      ...
   return result;
}

int main () {
   std::vector<unsigned long> result = findFibonacciPrimes(1, 100);
   // use result.size() to get the number of items in the vector.
   // use result[i]     to get the i-th item.
}

我看到很多潛在的錯誤。

這是導致您崩潰的錯誤:

給定您的主循環:

 while ( lowerBound < three < upperBound ) {
    if ( fermatPrimeTest(three) ) {
      result[i++] = three;
    }
    one = two;
    two = three;
    three = one + two;
  }

我認為您真的應該這樣說,以保護數組長度,而與算法停止無關。

 while ((i < maxElements) && (lowerBound < three) && (three < upperBound)) {
    if ( fermatPrimeTest(three) ) {
      result[i++] = three;
    }
    one = two;
    two = three;
    three = one + two;
  }

現在,我其余的評論:考慮到這一行:

return sizeof result / sizeof result[0];   // return size of array TODO!

sizeof(result)將始終返回4(或在64位編譯時為8),因為您正在計算指針的大小而不是靜態數組的sizeof。 編譯器不知道此指針確實是一個靜態大小的數組。

您可能想說:

return i;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM