什么导致分段错误?

时间:2010-02-20 18:57:22

标签: c++ segmentation-fault primes

我一直在尝试编写一个程序来确定一个数字是否为素数。我的基础是Eratosthenes的Sieve。无论如何,我的程序适用于小数字(15485863作品),但如果我使用大数字(例如17485863),我会收到分段错误。我使用的是unsigned long longs,并且认为我没有超过它们的最大值。我只是看不出我做错了什么。提前感谢您的任何帮助!

#include <iostream>
#include <limits>

using namespace std;

bool soe (unsigned long long);

int main (void)
{
 unsigned long long x = 17485863;
 bool q = soe(x);

 cout << x << " is ";
 if(q)
  cout << "prime." << endl;
 else
  cout << "not prime." << endl;

 return 0;
    }

    bool soe(unsigned long long input)
    {
 unsigned long long arrayLength = input%2 + input/2;
 unsigned long long index = 2;
 unsigned long long greatestMult = 0;
 bool array[arrayLength];

 array[0] = true; //ignore true values in the array
 array[1] = true;
 do{
  array[index] = false;
 }while(++index < arrayLength);

 index = 2;

 do
 {
  if(input%index != 0)
  {
   greatestMult = input/index;
   while(index*greatestMult > arrayLength)
    greatestMult--;
   do
   {
    array[index*greatestMult] = true;
   }while(--greatestMult > 0);

   do
   {
    if(!array[index])
     break;
   }while(++index < arrayLength);

  }
  else
  {
   cout << endl << input << " is divisble by " << index << endl;
   return false;
  }
 }while(index < arrayLength);

 return true;
    }

3 个答案:

答案 0 :(得分:3)

请注意,无论是长期还是使用变量来标注自动数组都不是C ++的一部分 - 它们是gcc提供的扩展,如果可移植性是个问题,则不应该使用它们。

要解决您的问题,请按如下方式确定数组的大小:

 bool array[arrayLength];
如果arrayLength值太大,

将导致堆栈溢出(从而导致seg错误)。请改用std :: vector,但要注意内存不是无限资源。

答案 1 :(得分:1)

在第24行你有:bool array[arrayLength];你不能像这样在堆栈上声明一个数组。程序在第29行崩溃。您需要使用new / delete;

在堆上声明它

有这样的效果(我可能有一两个泄漏,但你明白了);

 //Beginning on Line 28
 bool *array = new bool[arrayLength];

 array[0] = true; //ignore true values in the array
 array[1] = true;
 do{
  array[index] = false;
 }while(++index < arrayLength);

 index = 2;

 do
 {
  if(input%index != 0)
  {
   greatestMult = input/index;
   while(index*greatestMult > arrayLength)
    greatestMult--;
   do
   {
    array[index*greatestMult] = true;
   }while(--greatestMult > 0);

   do
   {
    if(!array[index])
     break;
   }while(++index < arrayLength);

  }
  else
  {
   cout << endl << input << " is divisble by " << index << endl;
   delete [] array;
   return false;
  }
 }while(index < arrayLength);

 delete [] array;
 return true;
    }

输出

g++ -g test.cpp
gdb ./a.out
...clipped...
(gdb) run 
Starting program: /Users/nextraztus/a.out 
Reading symbols for shared libraries ++. done

17485863 is divisble by 3
17485863 is not prime.

Program exited normally.
(gdb) 

答案 2 :(得分:0)

index * greatMult可能等于arrayLength,因此您可以覆盖数组末尾的最后一个元素。

同样在堆栈上分配大型数组可能会导致问题,具体取决于操作系统。有些系统会扩展堆栈,其他系统将无法扩展堆栈。