是什么导致了分段错误?

发布于 2024-08-22 06:42:12 字数 1363 浏览 2 评论 0原文

我一直在尝试编写一个程序来确定一个数字是否是质数。我是根据埃拉托斯特尼筛法(Sieve of Eratosthenes)来设计它的。无论如何,我的程序适用于小数字(15485863 有效),但如果我使用大数字(例如 17485863),我会收到分段错误。我正在使用无符号长整型,并且认为我没有超过它们的最大值。我只是不明白我做错了什么。预先感谢您的任何帮助!

#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;
    }

I have been attempting to write a program that will determine if a number is prime or not. I have based it off of the Sieve of Eratosthenes. Anyway, my program works for small numbers (15485863 works), but if I use large numbers (ex. 17485863) I receive a segmentation fault. I am using unsigned long longs and do not think I have surpassed their maximum value. I just don't see what I have done wrong. Thank you in advance for any assistance!

#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;
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

奢欲 2024-08-29 06:42:12

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

像这样确定数组的大小

 bool array[arrayLength];

为了解决您的问题,如果 arrayLength 值太大,则 将导致堆栈溢出(从而导致段错误)。使用 std::vector 代替,但要注意内存不是无限的资源。

Please note that neither long long nor using variables to dimension automatic arrays are part of C++ - they are extensions provided by gcc and should not be used if portability is an issue.

To address your problem, dimensioning an array like this:

 bool array[arrayLength];

will cause a stack overflow (and thus a seg fault) if the arrayLength value is too large. Use a std::vector instead, but be aware that memory is not an infinite resource.

无需解释 2024-08-29 06:42:12

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

On Line 24 you have: bool array[arrayLength]; You cannot declare an array on the stack like this. The program is crashing on line 29. You need to declare this on the heap using new/delete;

Something to this effect (I may have a leak or two in there, but you get the idea);

 //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;
    }

Output

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) 
阳光①夏 2024-08-29 06:42:12

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

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

It is possible for index*greatestMult to be equal to arrayLength, so you can overwrite the last element past the array end.

Also allocating large arrays on the stack like that can cause a problem depending on the operating system. Some systems will expand the stack that much, others will not be able to.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文