矢量重新分配,而不考虑储备

Vector reallocation regardless of reserve

本文关键字:不考虑 分配 新分配      更新时间:2023-10-16

假设我有一个std::vector<Group> groups。我要push_back很多Groupgroups.这就是为什么我reserve.我的问题是,当我保留groups时,成员v未初始化。但在push_back期间,Group bGroup c有不同的v大小。那么我们能不能说,即使reserve打电话,当我push_back时,重新分配是不可避免的?

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;
}

这里的关键是了解C++对象大小的工作原理。

在您的示例中:

struct Group
{
std::vector<int> v;
};

类型Group的对象在内存中具有恒定大小。这绝对是至关重要的。编译器需要预先知道Group的大小。这就是为什么sizeof(Group)是一个编译时常量。

现在..隐藏在vector里面是一个指针。同样,它是固定大小(4 或 8 个字节,具体取决于位数(。因此,您的vector也具有恒定的大小。此指针指向在堆上动态分配的内存块。这是存储元素的位置。同样,此块的大小是固定的,但可以重新分配,因此当矢量填满时,指针最终可能会指向一个新的更大的内存块。这些操作都不会使对象本身vectorGroup对象本身变大。

vector填满并变得"更大"时,vector对象本身的内存占用量保持不变。但是,该内部指针指向的内存(堆上其他地方的内存(将根据需要增长。

因此,当您调用reserve时,vector会预先确切地知道要保留多少动态内存。当您添加它们时,这不会受到Group内矢量中的许多元素的影响。从reserve调用的角度来看,元素大小在编译时是固定的。