2015-01-05 63 views
2

所以我有以下代碼:C++奇怪的std :: bad_alloc異常

#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]; 
+0

1)你做了什麼調試?什麼行引發異常。 2)如果你損壞了記憶,沒有什麼是「令人難以置信的」。 – PaulMcKenzie

+2

你超出你的陣列。 'j <= MAXN'時,'isNotPrime [j] = true'在'j'達到MAXN時不會成功。在這樣做的時候,你正在跺腳在內存中的下一個變量,它似乎是你的向量,它的第一個數據成員,這可能是指向向量動態內存牀的指針。改寫,並繁榮。在這個代碼中*不應該有...... <= MAXN' *。它應該是'... WhozCraig

+0

明顯的奇怪之處是for循環像'i <= MAXN'可能導致訪問無效內存(因爲數組是0..MAXN-1) – John3136

回答

6

的問題是在這裏:

for(int i = 2; i <= MAXN; ++i) 

的檢查應i < MAXN代替。 (或者,使數組有大小MAXN + 1。)

在某些時候,執行isNotPrime[MAXN] = true;,其溢出數組的邊界,造成未定義行爲。在實踐中,這會覆蓋下一個變量(primes)的一些內部字段,這會混淆std::vector實現,可能會導致它請求大量內存。

這也解釋了爲什麼切換變量順序「修復」它,因爲現在你正在塗寫別的東西而不是primes