通过构造函数为vector预分配内存失败
C++ memory preallocation for vector via constructor fails
我使用VS2013 (Win7 64)。我发现了一些奇怪的行为。当我使用reserve方法保留内存时,代码可以工作,但是当我通过构造函数保留内存时,它抛出bad_alloc
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;
}
原因是什么?
hlt已经在评论中回答了这个问题…
构造函数不
reserve
,它resize
s。有没有可能是内存用完了?
…所以在社区wiki上发布一个解释…
…
std::vector<int>* intVector = new std::vector<int>(elemNumber); // throws bad_alloc
…需要用默认构造的元素填充向量,因此它正在写入elemNumber
int
s所需的所有内存页面,并且初始size()
是elemNumber
,而…
std::vector<int>* intVector = new std::vector<int>();
intVector->reserve(elemNumber); //OK
…只是为内存保留虚拟地址——操作系统不需要找到实际的后备内存,直到稍后添加元素;初始size()
仍然是0
。
程序然后进入push_back
许多元素-对于第一种情况,它们是在vector
中已经存在的默认构造元素的之外的,这就是它耗尽内存的原因。
还请记住,在调整大小期间(由push_back
超过capacity
引起)暂时使用的内存随着容器变大而增加,容器倾向于填充容量的数量也会增加,因此它不必很快再次调整大小,并且所需的内存必须在虚拟地址空间中连续(这主要是32位应用程序的潜在问题)。
看一下下面的例子:
#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;
}
构造函数首先将vector的大小调整为5个元素。之后,再将5个元素压入vector容器,使vector容器的大小翻倍,并将前5个元素初始化为0。
如果使用保留函数,则vector的大小只有5*sizeof(int)和预分配的内存。
使用:vectorInt[i] = i;
与resize构造函数一起使用,将使vector的大小与使用reserve相同,并且不会抛出std::bad_alloc。
std::bad_alloc的原因很可能是内存耗尽。
我也得到了MSVS2015 RC上的bad_alloc
异常。然而,bad_alloc
不出现在构造行中。
第一行
std::vector<int>* intVector = new std::vector<int>(elemNumber);
为100000000个整数分配存储空间,然后循环:
for (int i = 0; i < elemNumber; ++i)
{
intVector->push_back(i);
}
增加了另外100000000个整数,在到达200000000(在我的例子中是150000000)的某个点上抛出bad_alloc
。
实际上,MSVC为225000000
值调用_Reallocate
,因为有一个函数_Grow_to
,如果可能的话,根据max_size()
,它试图通过50%
增长。
- 在c++中为我自己的基于指针的数组分配内存的正确方法
- 给定一个指向堆分配内存的指针,智能指针实现如何为其找到合适的释放函数?
- 如果 const 不分配内存,为什么我可以获取 const 的地址?
- 在函数中分配内存时出现问题
- 如何为 std::vector 分配内存,然后稍后为某些元素调用构造函数?
- constexpr new 如何分配内存?
- 在构造函数中分配内存失败是如何冒泡的
- LLVM 传递以在特定地址分配内存
- STL算法和back_inserter可以预分配空间吗?
- CudaMalloc 在分配内存时失败
- 如何将google::p rotobuf::消息直接序列化到预分配的内存中?
- 在不放置新运算符的情况下,在预分配的内存上使用虚函数初始化对象 - 这可能吗?如果没有,为什么
- 在预分配的内存中移动数据
- 为循环中多次调用的函数返回值预分配内存的正确方法是什么
- 为什么在预关注内存中创建对象慢,而不是单独为每个对象分配内存的对象
- 预分配内存空间供程序使用
- 如何为正在增长的Eigen::MatrixXd预分配内存
- 管理带有预分配内存和数组的析构函数
- 通过构造函数为vector预分配内存失败
- 管理预分配块的内存管理器