首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >通过构造函数为向量预先分配C++内存失败

通过构造函数为向量预先分配C++内存失败
EN

Stack Overflow用户
提问于 2015-07-23 10:56:47
回答 3查看 1.5K关注 0票数 4

我使用VS2013 (Win7 64)。我发现了一些奇怪的行为。当我使用备用方法预留内存时,代码可以工作,但是当我通过构造函数保留内存时,它会抛出bad_alloc。

代码语言:javascript
运行
复制
const int elemNumber = 100000000;
try
{
    //std::vector<int>* intVector = new std::vector<int>(elemNumber); // throws bad_alloc
    std::vector<int>* intVector = new std::vector<int>();
    intVector->reserve(elemNumber); //OK

    std::chrono::time_point<std::chrono::system_clock> start, end;
    start = std::chrono::system_clock::now();

    for (int i = 0; i < elemNumber; ++i)
    {
        intVector->push_back(i);
    }

    end = std::chrono::system_clock::now();
    std::chrono::duration<double> elapsed_seconds = end - start;
    std::cout << "Time interval: " << elapsed_seconds.count() << endl;
    delete intVector;
    cout << "Done" << endl;
}
catch (bad_alloc exc)
{
    cout << exc.what() << endl;
}

可能是什么原因?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-07-23 11:52:38

请看下面的示例:

代码语言:javascript
运行
复制
#include <iostream>
#include <chrono>
#include <vector>


int main()
{
    const int elemNumber = 5;
    try
    {
        std::vector<int> intVector(elemNumber); // throws bad_alloc

        std::chrono::time_point<std::chrono::system_clock> start, end;
        start = std::chrono::system_clock::now();

        for (int i = 0; i < elemNumber; ++i)
        {
            //intVector[i] = i;
            intVector.push_back(i);
        }

        //prints the vector
        for (auto& i : intVector)
        {
            std::cout << i << std::endl;
        }

        end = std::chrono::system_clock::now();
        std::chrono::duration<double> elapsed_seconds = end - start;
        std::cout << "Time interval: " << elapsed_seconds.count() << std::endl;
        std::cout << "Done" << std::endl;
    }
    catch (std::bad_alloc exc)
    {
        std::cout << exc.what() << std::endl;
    }


    std::cin.get();
    return 0;
}

构造函数首先调整向量的大小,使其具有5个元素。在此之后,它将5个元素推送到向量,使其大小翻倍,前5个元素被初始化为0。

如果要使用备用函数,则向量的大小将仅为5* size of (Int)和预先分配的内存。

使用:

代码语言:javascript
运行
复制
vectorInt[i] = i;

相反,与调整大小的构造函数一起,将导致向量的大小与要使用保留的大小相同,并且不会抛出std::bad_alloc。

std::bad_alloc的原因很可能是内存不足。

票数 1
EN

Stack Overflow用户

发布于 2015-07-23 11:44:19

hlt已经在评论中回答了这个问题..。

构造函数不reserve,它是resize的。是否可能内存不足?

...so发布了一个解释为社区wiki..。

这..。

代码语言:javascript
运行
复制
std::vector<int>* intVector = new std::vector<int>(elemNumber); // throws bad_alloc

...needs使用默认构造的元素填充向量,因此它将写入elemNumber ints所需的所有内存页,而初始size()elemNumber,而.

代码语言:javascript
运行
复制
std::vector<int>* intVector = new std::vector<int>();
intVector->reserve(elemNumber); //OK

...is只是为内存保留虚拟地址--在稍后添加元素之前,操作系统不需要找到实际的备份内存;初始的size()仍然是0

然后,程序会转到push_back --在第一种情况下,它们是在vector中已经构建的默认元素之外的元素,这就是它内存不足的原因。

还请记住,在调整大小期间使用的内存(由push_back超出capacity)随着容器的增大而增加,容器倾向于释放容量的数量也会增加,这样它就不必太快地重新调整大小,所需的内存必须在虚拟地址空间中是连续的(对于32位应用程序来说,这主要是一个潜在的问题)。

票数 3
EN

Stack Overflow用户

发布于 2015-07-23 11:43:38

我在bad_alloc RC上也得到了一个MSVS2015异常。然而,bad_alloc并不发生在构建行中。

首先,这一行:

代码语言:javascript
运行
复制
std::vector<int>* intVector = new std::vector<int>(elemNumber);

为100000000整数分配存储空间,然后再分配循环:

代码语言:javascript
运行
复制
for (int i = 0; i < elemNumber; ++i)
{
    intVector->push_back(i);
}

添加另外100000000个整数,其中在某个时候抛出到200000000 (在我的例子中为150000000) bad_alloc

实际上,MSVC调用_Reallocate来表示225000000值,因为有一个函数_Grow_to,如果可能的话,它会根据max_size()尝试由50%来增长。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31585343

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档