检查bitset的大小时出现分段错误

时间:2014-09-16 05:03:46

标签: c++ segmentation-fault bitset

当我尝试运行下面的代码时出现分段错误。我已经尝试评论代码的一些部分,并发现条件为j < is_prime.size()的while循环是罪魁祸首。这让我很困惑,因为我在它上面的for循环中对相同的值执行相同的检查,但是没有得到分段错误。

有人可以向我解释这里的问题是什么吗?

我在Linux 64上使用GCC 4.8.2。

#include <bitset>
#include <iostream>
using namespace std;

const size_t max_pandigital = 987654321;

int main()
{
    bitset<max_pandigital/3> is_prime;
    is_prime.set();                  // assume all numbers are prime
    is_prime[0] = false;             // 1 is not prime
    for(size_t i = 1; i < is_prime.size(); i++) {
        if(is_prime[i]) {
            int n;
            if(i%2 == 0) n = 3*i+1;
            else n = 3*i+2;
            size_t j = i;
            if(j%2 == 0) j += n-2;
            else j += n+2;
            while(j < is_prime.size()) {
                is_prime[j] = false;
                if(j%2 == 0) j += n-2;
                else j += n+2;
            }
        }
    }
    //cout << is_prime[899809363/3] << endl;
}

编辑:我实施了一些建议的更改。这是一个工作版本 - 运行在〜13s。我认为最大的瓶颈是为bool矢量分配42MB。谢谢!

#include <iostream>
#include <vector>
using namespace std;

const size_t max_pandigital = 987654321;

int main()
{
    vector<bool> not_prime(max_pandigital/3);
    not_prime[0] = true;             // 1 is not prime
    for(size_t i = 1; i < not_prime.size(); i++) {
        if(~not_prime[i]) {
            int n;
            if(i%2 == 0) n = 3*i+1;
            else n = 3*i+2;
            size_t j = i;
            if(j%2 == 0) j += n-2;
            else j += n+2;
            while(j < not_prime.size()) {
                not_prime[j] = true;
                if(j%2 == 0) j += n-2;
                else j += n+2;
            }
        }
    }
    cout << not_prime[899809363/3] << endl; // prime
    cout << not_prime[100017223/3] << endl; // pseudoprime
}

2 个答案:

答案 0 :(得分:1)

当你弄乱参考或fencepost时,你不能保证会出现段错误!行为是&#34;未定义&#34;,并且跟踪可能非常麻烦。使用像'valgrind&#39;这样的东西。找到确切的第一个不良时刻。

答案 1 :(得分:1)

如果注释掉了注释,并且我运行了你的代码,那么由于堆栈溢出我会得到一个段错误。 (即使代码仍然被注释掉,堆栈仍然溢出,这解释了你所看到的)。

典型系统默认为1兆字节的堆栈大小;但是你的bitset需要大约40兆的存储空间。

要解决此问题,您可以:

  • 动态分配您的bitset
  • 使用其他容器,例如vector<bool>
  • 告诉您的环境使用更大的堆栈大小

动态分配的一个例子可能是:

unique_ptr< bitset<max_pandigital/3> > ip { new bitset<max_pandigital/3> };
auto &is_prime = *ip;

和其余代码相同。