假设我有一个这样的对象:
struct MyObject
{
int someId;
std::vector<int> innerVector;
MyObject(int a)
{
innerVector.reserve(a);
}
};
我试着用这种方式保留一个向量MyObject
:
std::vector<MyObject> myObjects;
myObjects.reserve(maxItemsToBeAllowed);
如果每个MyObject
上的innerVector
向量的大小不可预测,它如何保留内存?它是否只是“尝试”,如果innerVector
更大的情况下在运行时重新分配?
3条答案
按热度按时间brccelvz1#
类型的大小永远是不可预测的。它在编译时总是已知的,并且在程序的整个生命周期中永远不会改变。
std::vector
在vector对象的内存中不包含它的元素。vector对象包含一些指向动态分配内存的指针。vsmadaxz2#
请记住,
std::vector
的内核很可能是使用动态内存分配来存储的,因此基本对象的大小是可以预测的,并且是预先知道的。它所做的就是在调用
reserve(n)
时保留 N 倍的占用空间。一旦这些条目被使用,它们可能需要额外的分配,除非,例如,您只是将它们保留为空。换句话说,
sizeof(std::vector<X>)
是可预测的。这种结构的总内存成本是完全不同的。另一方面,如果你有
std::array<std::array<X>>
,那就完全不同了。它们的行为更像C数组。7cjasjjr3#
std::vector::reserve
只是确保可以创建一定数量的元素,而无需重新分配向量的后备存储。使用此函数不会创建新元素。(如果需要重新分配内存,我将忽略那些需要从现有元素中移动构造的元素。)下面的代码仍然会导致后备存储器的最佳分配数量:
如果内部向量的大小对于所有
MyObject
s都是,则该逻辑仍然使用用于向量的备份存储的最佳分配数。上面的代码仍然只有一个外部向量的分配并且每个
MyObject
创建一个分配如果不更改类,则无法改进此数量,因为每个向量需要一个分配。(为了简单起见,我忽略了从未填充任何元素的向量;如果一些向量保持为空,则分配的数量仍然是最优的。)