2016-03-05 42 views
1

我需要在我的項目中創建一個非常大的數組。我嘗試了3種方法,但都是bad_alloc。我無法理解,因爲我的電腦的內存是10GB。爲什麼bad_alloc在新建數組,重新調整向量和push_back向量時?

這是我在MSVC2015 x86模式下的實現。

CODE1

#include<fstream> 
#include<iostream> 
#include<string> 
#include<vector> 
using namespace std; 
const long long MEM_SIZE = 1LL * 1024LL * 1024LL * 1024LL; // available memory 1GB 
typedef struct MyClass { 
    int a; 
    unsigned char b,c,d; 
    size_t e,f; 
    double g, h; 
}; 
int main() { 
    MyClass *mc = new MyClass[MEM_SIZE/sizeof(MyClass)]; 
    cout << "done!" << endl; 
    return 0; 
} 

CODE2

#include<fstream> 
#include<iostream> 
#include<string> 
#include<vector> 
using namespace std; 

const long long MEM_SIZE = 1LL * 1024LL * 1024LL * 1024LL; // available memory 1GB 
typedef struct MyClass { 
    int a; 
    unsigned char b,c,d; 
    size_t e,f; 
    double g, h; 
}; 
int main() { 
    vector<MyClass> myv; 
    myv.resize(MEM_SIZE/sizeof(MyClass)); 
    cout << "done!" << endl; 
    return 0; 
} 

CODE3

#include<fstream> 
#include<iostream> 
#include<string> 
#include<vector> 
using namespace std; 
const long long MEM_SIZE = 1LL * 1024LL * 1024LL * 1024LL; // available memory 1GB 
typedef struct MyClass { 
    int a; 
    unsigned char b,c,d; 
    size_t e,f; 
    double g, h; 
}; 
int main() { 
    vector<MyClass> myv; 
    MyClass tmp; 
    for (int i = 0; i < 12000000; i++){ 
     tmp.a = i; 
     myv.push_back(tmp); 
    } 
    cout << "done!" << endl; 
    return 0; 
} 

MyClass的大小是32字節,我將可用內存設置爲1GB,所以數組長度爲1GB/32B = 33554432。

至於CODE1和CODE2,數組大小爲1GB,遠遠小於PC的RAM,爲什麼bad_alloc

至於CODE3,我知道push_back的時候,vector的容量會翻倍,但是它也比PC的RAM少。在CODE3中,當i==11958657墜毀。

但是,當我建立和運行在x64模式,一切都很好。據我所知,x86的堆大約是2GB,爲什麼我的1GB陣列崩潰?

我該如何做x86模式?

+1

這是一個合法的問題,我不明白downvotes。 –

+1

可能是'vector :: max_size()'可以提供幫助。 [鏈接](http://www.cplusplus.com/reference/vector/vector/max_size/) –

+0

使用'std :: deque'而不是'std :: vector'有什麼區別? –

回答

1

一個數組在內存中必須是連續的,所以你不只需要1 GB的內存,你需要在一個塊中。即使你有足夠的空閒虛擬內存(物理內存並不重要),內存碎片可能會阻止該分配。

+0

非常好的一點;因此我的評論應該嘗試'std :: deque'。不過,我很確定你的意思是寫「連續」而不是「連續」。 –

+0

如果內存鄰接是問題,那麼deque不會解決問題。儘管標準並不要求雙端分配連續內存,但操作系統在請求內存時仍會嘗試分配連續的塊。 (至少在Windows上,不知道這是否適用於Linux等) –

+0

@CodyGray:我相當肯定這是錯誤的。標準並不「禁止」內存是連續的,但據我所知,它要求在前端和後端的插入操作保持所有指針的有效性,如果它需要重新分配整個內存塊,則這是不可能的。此外,它需要在開始時插入(分期付款)恆定的複雜性。 – Tannin