【问题标题】:This code works in debug mode but not in release mode c++此代码在调试模式下工作,但在发布模式下不工作 c++
【发布时间】:2017-11-26 15:13:23
【问题描述】:

我正在尝试生成多达 10 亿个素数。此代码在调试模式下工作正常,但在发布模式下,它在 2 3 后崩溃。有人可以在这里提供帮助吗?

void SieveOfEratosthenes(size_t n)
{

// Create a boolean array "prime[0..n]" and initialize
// all entries it as true. A value in prime[i] will
// finally be false if i is Not a prime, else true.
bool* prime = new bool[1000000000];

memset(prime, true, sizeof(prime));

for (size_t p = 2; p*p <= n; p++)
{
    // If prime[p] is not changed, then it is a prime
    if (prime[p] == true)
    {
        // Update all multiples of p
        for (size_t i = p * 2; i <= n; i += p)
            prime[i] = false;
    }
}

// Prsize_t all prime numbers
for (size_t p = 2; p <= n; p++)
    if (prime[p])
        cout << p << " ";
}

int main()
{
size_t n = 1000000000;
cout << "Following are the prime numbers smaller "
    << " than or equal to " << n << endl;
SieveOfEratosthenes(n);

getchar();
return 0;
}

【问题讨论】:

  • 它到底是在哪里崩溃的?错误是什么?有关如何提出好问题的详细信息,请参阅How to Ask
  • memset(prime, true, sizeof(prime)); 没有做你认为它做的事情,并使你的代码一团糟。您应该阅读一本好的 C++ 书籍。
  • 您可以使用std::vector&lt;bool&gt; prime(n, true); 并一步完成初始化,而不是摆弄 C 函数。

标签: c++ release primes


【解决方案1】:

一个问题是memset 调用是错误的。您需要将其称为memset(prime, true, sizeof(bool) * 1000000)sizeof(prime) 将返回 8,这是您正在测试的计算机上最可能的指针大小。

【讨论】:

  • 这是否有效取决于实现,甚至在哪里有效,这不是一个好主意。
【解决方案2】:

这里有两个主要问题。

首先,这是不正确的:

memset(prime, true, sizeof(prime));

表达式sizeof(prime) 为您提供指针 的大小(很可能是4 或8),而不是它所指向的大小。所以你只设置 4 或 8 个字节。你可以这样做:

memset(prime, true, sizeof(*prime) * n`);

但是,这取决于 sizeof(*prime) 是否为 1。如果不是,则值将不是您所期望的。正确的做法是:

for (i=0; i<n; i++) {
    prime[i] = true;
}

另一个问题是for 循环中的限制:

for (size_t p = 2; p*p <= n; p++)
...
for (size_t i = p * 2; i <= n; i += p)
...
for (size_t p = 2; p <= n; p++)

在每一个中,您都在检查用作数组索引的循环计数器是否为&lt;= n。由于您的数组具有n 元素,因此该数组中的有效索引从0 到n-1。而且因为当索引为n 时您没有退出循环,所以您最终会读/写超出数组的末尾。这会调用未定义的行为。

你需要把这些循环条件改成&lt; n

for (size_t p = 2; p*p < n; p++)
...
for (size_t i = p * 2; i < n; i += p)
...
for (size_t p = 2; p < n; p++)

另外,在你的SieveOfEratosthenes 末尾一定要delete[] prime;,这样你就不会泄漏内存。

【讨论】:

  • 这是否有效取决于实现,甚至在哪里有效,这不是一个好主意。请教初学者正确的良好做法,而不是“修复”他们糟糕的试错结果。
  • @BaummitAugen 已更新以正确初始化数组。
  • 使用循环,答案在技术上是正确的,但仍然支持不好的做法。如果你选择回答这样的问题,至少要做到正确,并教他们如何正确使用容器,而不是 90 年代风格的内存管理。
  • 为此,std::vector&lt;bool&gt; prime(1000000000);,即使有 std::vector&lt;bool&gt; 的缺点,也足够了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 2018-07-31
  • 2023-01-11
相关资源
最近更新 更多