我使用VS2013 (Win7 64)。我发现了一些奇怪的行为。当我使用备用方法预留内存时,代码可以工作,但是当我通过构造函数保留内存时,它会抛出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;
}
可能是什么原因?
发布于 2015-07-23 11:52:38
请看下面的示例:
#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)和预先分配的内存。
使用:
vectorInt[i] = i;
相反,与调整大小的构造函数一起,将导致向量的大小与要使用保留的大小相同,并且不会抛出std::bad_alloc。
std::bad_alloc的原因很可能是内存不足。
发布于 2015-07-23 11:44:19
hlt已经在评论中回答了这个问题..。
构造函数不
reserve
,它是resize
的。是否可能内存不足?
...so发布了一个解释为社区wiki..。
这..。
std::vector<int>* intVector = new std::vector<int>(elemNumber); // throws bad_alloc
...needs使用默认构造的元素填充向量,因此它将写入elemNumber
int
s所需的所有内存页,而初始size()
是elemNumber
,而.
std::vector<int>* intVector = new std::vector<int>();
intVector->reserve(elemNumber); //OK
...is只是为内存保留虚拟地址--在稍后添加元素之前,操作系统不需要找到实际的备份内存;初始的size()
仍然是0
。
然后,程序会转到push_back
--在第一种情况下,它们是在vector
中已经构建的默认元素之外的元素,这就是它内存不足的原因。
还请记住,在调整大小期间使用的内存(由push_back
超出capacity
)随着容器的增大而增加,容器倾向于释放容量的数量也会增加,这样它就不必太快地重新调整大小,所需的内存必须在虚拟地址空间中是连续的(对于32位应用程序来说,这主要是一个潜在的问题)。
发布于 2015-07-23 11:43:38
我在bad_alloc
RC上也得到了一个MSVS2015异常。然而,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调用_Reallocate
来表示225000000
值,因为有一个函数_Grow_to
,如果可能的话,它会根据max_size()
尝试由50%
来增长。
https://stackoverflow.com/questions/31585343
复制相似问题