【问题标题】:C++ : Segmentation fault (core dumped) issueC++:分段错误(核心转储)问题
【发布时间】:2018-07-28 06:06:10
【问题描述】:

Sieve of eratosthenes 在 C++ 中的实现:

当我运行我的 C++ 程序时,我得到了

“分段错误(核心转储)”

它编译没有任何错误。

在这个程序中,我试图打印两个数字 a 和 b 之间的所有素数。

#include <iostream>
#include <string.h>
#define MAX 1000000

using namespace std;

// Print all primes s.t. a <= prime <= b
int main()
{
    int t; // no of test cases
    cin>>t;

    bool prime[MAX + 1];    // a[i] = true for i = prime
    long int count_primes_lte_me[MAX + 1]; // a[i] = Count ( primes ) <= i
    long int counter_of_visited_primes;

    prime[0] = prime[1] = false;
    for(int i = 2 ; i <= MAX ; i++)
    {
        if(prime[i] == true)
            count_primes_lte_me[i] = ++counter_of_visited_primes;

        for(int j = i*i ; j <= MAX ; j += i)  // sieve of eratosthenes
            prime[j] = false;
    }

    long int a , b;
    while(t--)
    {
        cin>>a>>b;
        cout<<count_primes_lte_me[b] - count_primes_lte_me[a - 1]<<endl;
    }

    return 0;
}

【问题讨论】:

  • 只需在调试器中运行程序或在调试器中打开核心文件,您就会看到崩溃的位置和原因
  • for(int i = 2 ; i &lt;= MAX ; i++) 这可能是错误的
  • @EdHeal 有什么问题?
  • 是的,但这不是问题。个人选择:)
  • @EdHeal:如果您不阅读其余代码,这只是“可能是错误的”。

标签: c++ segmentation-fault


【解决方案1】:

尝试为MAX 设置较小的值。在堆栈上分配如此巨大的数组会产生(初始)问题。然后替换为动态分配:

bool *prime = new bool[MAX+1];
if (prime==nullptr) // error

...

delete [] prime;

您也可以使用静态分配(将您的变量定义为全局)。

最好使用一些合适的容器,例如bitset

注意i*i可能会溢出,所以可能会出现其他问题...

【讨论】:

  • 它适用于较小的最大值。但我需要使用 MAX 1000000 运行程序
  • 按照你说的尝试动态分配..等等。
  • 这大约是std::vector 出现的时间,所以在动态数组的第一个迹象时节省一天的时间。 (听起来很老套,我知道)
  • 动态分配完成了这项工作。更改为 bool *prime = new bool[MAX + 1];工作。也改了 long *count_primes_lte_me = new long[MAX + 1];
  • @JayTeli 你也可以使用std::fill_n
【解决方案2】:

i * i 将在i &lt;= MAX 的内部循环中溢出。这可能会由于负 j 而导致段错误。使用更大的整数类型:long long j = (long long)i * i

为了正确起见,您需要将 prime 数组初始化为 true 并将计数数组初始化为 0 值。

【讨论】:

  • @JayTeli 你想告诉我什么?
  • 不管这实际上不是问题,而是i*i可能溢出的问题。
  • @JayTeli 不,它不一定会失败,j 可以变成负数
  • @yassin 程序在进入循环前崩溃。
【解决方案3】:

你有一百万的最大值......我试图减少它并且没有错误但仍然没有任何效果......试试这个

/************************************
***Array names as pointers***********
************************************/
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
    const int MAX = 10000;
    long prime[MAX] = { 2, 3, 5 };
    long trial = 5;
    int count = 3;
    int found = 0;

    do
    {
        trial += 2;
        found = 0;
        for (int i = 0; i < count; i++)
        {
            found = (trial % *(prime + i)/* prime[i] */) == 0;

            if (found)
                break;
        }
        if (found == 0)
            *(prime + count++)/* prime[count++] */ = trial;
    } while (count < MAX);

    for (int i = 0; i < MAX; i++)
    {
        if (i % 5 == 0)
            cout << endl;
        cout << setw(10) << *(prime + i)/* prime[i] */;
    }
    cout << endl;
    return 0;
}

【讨论】:

    猜你喜欢
    • 2015-06-27
    • 1970-01-01
    • 2021-06-03
    • 2023-04-04
    • 2022-01-14
    • 2017-02-25
    • 2016-07-12
    • 2018-03-16
    • 1970-01-01
    相关资源
    最近更新 更多