C++ 奇怪 std::bad_alloc 异常
C++ Strange std::bad_alloc exception
所以我有以下代码:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
const int MAXN = 1000000;
int isNotPrime[MAXN];
vector<int> primes;
void sieve()
{
for(int i = 2; i <= sqrt(MAXN); ++i)
{
if(isNotPrime[i]) continue;
for(int j = i*i; j <= MAXN; j += i)
{
isNotPrime[j] = true;
}
}
for(int i = 2; i <= MAXN; ++i)
{
if(!isNotPrime[i])
{
primes.push_back(i);
}
}
}
int main()
{
ios::sync_with_stdio(false);
sieve();
return 0;
}
我无法理解的是为什么我的程序在执行时会抛出std::bad_alloc异常。更令人难以置信的是,当我交换行 int isNotPrime[MAXN];
和 vector<int> primes;
时,程序会按预期执行。
像这样交换:
vector<int> primes;
int isNotPrime[MAXN];
问题出在这里:
for(int i = 2; i <= MAXN; ++i)
检查应该是 i < MAXN
。 (或者,使数组的大小为 MAXN + 1
。)
在某些时候,isNotPrime[MAXN] = true;
执行,溢出数组的边界,导致未定义的行为。实际上,这会覆盖下一个变量 (primes
) 的某些内部字段,这会混淆 std::vector
实现,可能导致它请求大量内存。
这也解释了为什么要切换变量顺序 "fixes",因为现在你正在涂写其他东西而不是 primes
。
所以我有以下代码:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
const int MAXN = 1000000;
int isNotPrime[MAXN];
vector<int> primes;
void sieve()
{
for(int i = 2; i <= sqrt(MAXN); ++i)
{
if(isNotPrime[i]) continue;
for(int j = i*i; j <= MAXN; j += i)
{
isNotPrime[j] = true;
}
}
for(int i = 2; i <= MAXN; ++i)
{
if(!isNotPrime[i])
{
primes.push_back(i);
}
}
}
int main()
{
ios::sync_with_stdio(false);
sieve();
return 0;
}
我无法理解的是为什么我的程序在执行时会抛出std::bad_alloc异常。更令人难以置信的是,当我交换行 int isNotPrime[MAXN];
和 vector<int> primes;
时,程序会按预期执行。
像这样交换:
vector<int> primes;
int isNotPrime[MAXN];
问题出在这里:
for(int i = 2; i <= MAXN; ++i)
检查应该是 i < MAXN
。 (或者,使数组的大小为 MAXN + 1
。)
在某些时候,isNotPrime[MAXN] = true;
执行,溢出数组的边界,导致未定义的行为。实际上,这会覆盖下一个变量 (primes
) 的某些内部字段,这会混淆 std::vector
实现,可能导致它请求大量内存。
这也解释了为什么要切换变量顺序 "fixes",因为现在你正在涂写其他东西而不是 primes
。