Eratosthenes算法的C ++ Sieve导致堆栈溢出

时间:2014-04-29 01:07:16

标签: c++ algorithm primes sieve-of-eratosthenes

我正在研究一个简单的Eratosthenes Sieve算法,代码如下:

int main()
{

    const int n = 1000000;

    int sqrn = floor(sqrt(n));

    bool primes[n + 1] = { 0 }; // false means prime, true not prime

    primes[0] = true;
    primes[1] = true;

    for (int i = 2; i <= sqrn; i++){

        if (primes[i] == false) {
            int j = i + i;
            while (j<=n-1){
                primes[j] = true;
                j = j + i;
            }
        }
    }
}

我的主要问题是,如果我尝试将搜索数组设置为大于n = 1000000,则此代码会导致堆栈溢出错误。我不确定这是因为编程错误还是因为程序无法容纳大于10 ^ 6个条目的布尔数组?任何建议都表示赞赏。

我遇到的另一个小问题是,在for-loop语句之外设置n的平方根的评估是否提高了执行速度。

谢谢

3 个答案:

答案 0 :(得分:2)

您正在堆栈上分配primes数组。堆栈只有有限的尺寸(它非常大,但它仍然有限)。你可以:

  • 在全局数据区域中分配您的数组,或
  • 使用new
  • 在堆上分配您的数组

答案 1 :(得分:1)

堆栈溢出可能是因为您的堆栈大小不超过1MB(或1MB,具体取决于您的定义)。 bool通常是1个字节。尝试在堆上分配primes数组(使用new[])以避免堆栈大小限制。请记住使用delete[]释放数组。

此算法的n的素数也是不正确的。您想将j<=n-1更改为j<=n

答案 2 :(得分:1)

而不是bool primes[n + 1] = { 0 };,请执行:

std::vector<bool> primes(n+1);

这为足够的素数分配非堆栈空间,并将它们全部初始化为false

这个版本的另一个优点是编译器可能专门使用每个值一位,而你的版本每个值使用一个字节。

可能具有更好性能的类似替代方案(但只有在编译时知道大小时才可能)

std::bitset<n+1> primes;

如果您查看其文档,您可以提高代码的性能。