2016-03-05 95 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