当我尝试运行下面的代码时出现分段错误。我已经尝试评论代码的一些部分,并发现条件为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
}
答案 0 :(得分:1)
当你弄乱参考或fencepost时,你不能保证会出现段错误!行为是&#34;未定义&#34;,并且跟踪可能非常麻烦。使用像'valgrind&#39;这样的东西。找到确切的第一个不良时刻。
答案 1 :(得分:1)
如果注释掉了注释,并且我运行了你的代码,那么由于堆栈溢出我会得到一个段错误。 (即使代码仍然被注释掉,堆栈仍然溢出,这解释了你所看到的)。
典型系统默认为1兆字节的堆栈大小;但是你的bitset需要大约40兆的存储空间。
要解决此问题,您可以:
vector<bool>
动态分配的一个例子可能是:
unique_ptr< bitset<max_pandigital/3> > ip { new bitset<max_pandigital/3> };
auto &is_prime = *ip;
和其余代码相同。