C++ 过早达到最大向量大小

C++ 过早达到最大向量大小,c++,stdvector,C++,Stdvector,我正在测试我能在我的计算机上生成多大的一维向量。为此,我使用以下MWE: #include <iostream> #include <vector> using namespace std; int main() { vector<double> vec; const unsigned long long lim = 1E8; for(unsigned long long i=0; i<lim; i++) {

我正在测试我能在我的计算机上生成多大的一维向量。为此,我使用以下MWE:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<double> vec;

    const unsigned long long lim = 1E8;
    for(unsigned long long i=0; i<lim; i++)
    {
        vec.push_back(i);
    }
    cout << vec.max_size() << endl; //outputs 536.870.911 on my 32-bit system


    return 0;
}
如图所示,max_size告诉我std::vector在我的系统上可以包含536.870.911元素。然而,当我运行上面的MWE时,我得到了错误

在抛出'std::bad_alloc'实例后调用terminate what:std::bad_alloc

我的计算机有2GB内存,但1E8整数只占381MB,所以我不明白为什么会出现错误?

1E8=100000000,sizeofdouble=8[在几乎所有系统中],所以762MB。现在,如果我们从一个向量开始,比如说,16个元素,当它超出当前大小时,它会加倍,以获得1E8元素的空间,我们得到以下序列:

16、32、64、128、256。。。67108864 64M条目,下一个是134217728,占用8*128M=1GB,同时您还必须有空间容纳64M*8=512MB块,以便从中复制旧数据。考虑到32位进程中没有完整的2GB可用空间,因为堆栈、程序代码、DLL和其他诸如此类的东西占用了一些内存,当已经占用超过512MB的空间时,很难找到1GB的连续空间区域

我不能像我记忆中想象的那样适应的问题并不是一个不寻常的问题

一种解决方案是使用std::vector::reserve预先分配足够的空间。这更有可能奏效,因为您只需要一个大的分配,而不是两个——而且它也不会比762MB需要更多,因为它被分配到了正确的大小,而不是当前大小的任意两倍

1E8=100000000,sizeofdouble=8[在几乎所有系统中],因此762MB。现在,如果我们从一个向量开始,比如说,16个元素,当它超出当前大小时,它会加倍,以获得1E8元素的空间,我们得到以下序列:

16、32、64、128、256。。。67108864 64M条目,下一个是134217728,占用8*128M=1GB,同时您还必须有空间容纳64M*8=512MB块,以便从中复制旧数据。考虑到32位进程中没有完整的2GB可用空间,因为堆栈、程序代码、DLL和其他诸如此类的东西占用了一些内存,当已经占用超过512MB的空间时,很难找到1GB的连续空间区域

我不能像我记忆中想象的那样适应的问题并不是一个不寻常的问题


一种解决方案是使用std::vector::reserve预先分配足够的空间。这更有可能奏效,因为您只需要一个大的分配,而不是两个——而且它也不会比762MB需要更多,因为它被分配到了正确的大小,而不是当前大小的任意两倍

她是这么说的?1e8 int消耗多少空间与双倍向量无关…你在哪个平台上?她是这么说的?1e8 int消耗多少空间与双倍向量无关…你在哪个平台上?但它长大后真的会加倍吗?是的,我知道的向量就是这样工作的。微软和GNU标准C++库都是这样工作的,我不知道还有一个不这样做。而且,即使它不需要,也需要旧的+新的大小向量,如果我们在这个东西上加上不同的乘法器,它将有同样的效果。除了新的会比旧的大x倍-简单地说x不是2-你仍然会耗尽内存,因为新的和旧的在同一时间没有空间,即使之前或之后有大量的内存空闲…但是当它增长时它真的会加倍吗?是的,我知道的向量就是这样工作的。微软和GNU标准C++库都是这样工作的,我不知道还有一个不这样做。而且,即使它不需要,也需要旧的+新的大小向量,如果我们在这个东西上加上不同的乘法器,它将有同样的效果。除了新的会比旧的大x倍-简单地说x不是2-你仍然会耗尽内存,因为没有空间同时容纳新的和旧的,即使之前或之后有大量的可用内存。。。。