我使用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;
}
可能是什么原因?
答案 0 :(得分:2)
hlt已经在评论中回答了这个问题......
构造函数不是
reserve
,而是resize
。你有可能只是内存不足吗?
...所以将解释发布为社区维基...
此...
std::vector<int>* intVector = new std::vector<int>(elemNumber); // throws bad_alloc
...需要使用默认构造的元素填充向量,因此它写入elemNumber
int
所需的所有内存页面,并且初始size()
为{ {1}},而......
elemNumber
...只是为内存保留虚拟地址 - 在稍后添加元素之前,操作系统不需要找到实际的后备内存;最初的std::vector<int>* intVector = new std::vector<int>();
intVector->reserve(elemNumber); //OK
仍为size()
。
程序然后转到0
许多元素 - 对于第一种情况,它们另外已经存在于push_back
中的那些默认构造元素中,这就是为什么它的内存不足。
还要记住,在调整大小期间暂时使用的内存(由vector
引起的push_back
)会随着容器变大而增加,容器倾向于填充容量的数量也会增加不需要太快再次调整大小,并且所需的内存必须在虚拟地址空间中连续(这对于32位应用程序来说主要是一个潜在的问题)。
答案 1 :(得分:0)
我也在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个整数,在某个点上,在200,00000(在我的情况下为150000000)bad_alloc
被抛出的路上。
实际上,MSVC会针对_Reallocate
值调用225000000
,因为有一个函数_Grow_to
根据50%
尝试增加max_size()
。< / p>
答案 2 :(得分:0)
看看下面的例子:
#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 * sizeof(int)和预分配的内存。
使用:
vectorInt[i] = i;
与resize构造函数一起使用将导致向量与使用reserve时的大小相同,并且不会抛出std :: bad_alloc。
std :: bad_alloc的原因很可能就是内存不足。