【问题标题】:What is causing a segmentation fault?是什么导致分段错误?
【发布时间】:2010-02-20 18:57:21
【问题描述】:

我一直在尝试编写一个程序来确定一个数字是否是素数。我的基础是埃拉托色尼筛法。无论如何,我的程序适用于小数字(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;
    }

【问题讨论】:

  • 你调试过程序吗?能否给出发生分段错误的行号?

标签: c++ segmentation-fault primes


【解决方案1】:

请注意,long long 和使用变量来标注自动数组都不是 C++ 的一部分——它们是 gcc 提供的扩展,如果存在可移植性问题,则不应使用它们。

要解决您的问题,请像这样对数组进行标注:

 bool array[arrayLength];

如果 arrayLength 值太大,将导致堆栈溢出(从而导致段错误)。请改用 std::vector,但请注意内存不是无限资源。

【讨论】:

    【解决方案2】:

    在第 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) 
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 2020-09-15
        • 2012-04-19
        • 1970-01-01
        • 1970-01-01
        • 2018-06-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多