此代码在调试模式下工作,但在发布模式下不工作 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<bool> 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++)
在每一个中,您都在检查用作数组索引的循环计数器是否为<= 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;
,这样你就不会泄漏内存。
【讨论】:
这是否有效取决于实现,甚至在哪里有效,这不是一个好主意。请教初学者正确的良好做法,而不是“修复”他们糟糕的试错结果。 @BaummitAugen 已更新以正确初始化数组。 使用循环,答案在技术上是正确的,但仍然支持不好的做法。如果你选择回答这样的问题,至少要做到正确,并教他们如何正确使用容器,而不是 90 年代风格的内存管理。 为此,std::vector<bool> prime(1000000000);
,即使有 std::vector<bool>
的缺点,也足够了。以上是关于此代码在调试模式下工作,但在发布模式下不工作 c++的主要内容,如果未能解决你的问题,请参考以下文章
react-native-geolocation-service 在调试模式下正常工作,但在发布模式下不工作
在发布模式下崩溃但在调试模式下不崩溃的 ActiveX 控件