此代码在调试模式下工作,但在发布模式下不工作 c++

Posted

技术标签:

【中文标题】此代码在调试模式下工作,但在发布模式下不工作 c++【英文标题】:This code works in debug mode but not in release mode 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 函数。 【参考方案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; 的缺点,也足够了。

以上是关于此代码在调试模式下工作,但在发布模式下不工作 c++的主要内容,如果未能解决你的问题,请参考以下文章

react-native-geolocation-service 在调试模式下正常工作,但在发布模式下不工作

在发布模式下崩溃但在调试模式下不崩溃的 ActiveX 控件

OpenCV垫在调试模式下不工作

ionic iOS FCM 在开发模式下工作,但在生产模式下不工作

为啥我的应用程序在发布模式下崩溃但在调试模式下不崩溃?

Firebase google 身份验证在发布模式下不起作用