该代码在调试模式下工作,但在发布模式C 中不起作用

This code works in debug mode but not in release mode c++

本文关键字:模式 布模式 不起作用 调试 代码 工作      更新时间:2023-10-16

我正在尝试生成高达10亿的质数。此代码在调试模式下运行良好,但是在发行模式下它会在2后崩溃3. 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;
}

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

这里有两个主要问题。

首先,这是不正确的:

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++)

在每个中,您都在检查您用作数组索引的循环计数器是否为 <= n。由于您的数组具有n元素,因此此数组中的有效索引从0到n-1。而且,由于当索引为n时,您不会退出循环,因此您最终会在数组的末端读取/写作。这调用了未定义的行为。

您需要将这些循环条件更改为< 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;,以免泄漏内存。