假设我有std::vector<Group> groups
。我将push_back
经常Group
转到groups
。这就是我reserve
的原因。我的问题是,当我保留groups
时,成员v
未被初始化。但在push_back
期间,Group b
和Group c
的大小不同v
。那么即使push_back
调用reserve
,我们可以说重新分配是不可避免的吗?
struct Group
{
std::vector<int> v;
};
int main()
{
std::vector<Group> groups;
groups.reserve(1e6);
Group b, c;
b.v.resize(1000);
c.v.resize(2000);
groups.push_back(b);
groups.push_back(c);
return 0;
}
答案 0 :(得分:0)
这里的关键是理解C ++对象大小的工作原理。
在你的例子中:
struct Group
{
std::vector<int> v;
};
Group
类型的对象在内存中具有恒定的大小。这绝对至关重要。编译器需要预先知道Group
的大小。这就是sizeof(Group)
是编译时常量的原因。
现在..隐藏在vector
内是一个指针。同样,它是固定大小(4或8字节,具体取决于位数)。所以你的vector
也有不变的大小。该指针指向在堆上动态分配的内存块。这是元素的存储位置。同样,这个块是固定大小的,但可以重新分配,因此当向量填满时,指针可能最终指向一个新的更大的内存块。这些操作都不会使vector
或Group
对象本身更大。
当vector
填满并变得“更大”时,vector
对象本身的内存占用量仍为常量。但是,内部指针所指向的内存(堆上其他位置的内存)将根据需要增长。
因此,当您致电reserve
时,vector
会提前知道要保留多少动态内存。当您添加它们时,Group
中的向量中的许多元素都不会影响这一点。从reserve
调用的角度来看,元素大小在编译时是固定的。