更改向量<string>中字符串的大小

Changing the size of a string in a vector<string>

本文关键字:字符串 string 向量 lt gt      更新时间:2023-10-16

当向量的一个或多个元素改变大小时,向量会发生什么?

详细说明,

#include <string>
#include <vector>
using namespace std;
int main() {
    vector<string> v;
    v.push_back("first string");
    v.push_back("2nd string");
    v[0] += " has increased in size";
}

在"v[0]+=…"时会发生什么?是否会进行大规模重新分配,以保持字符串和向量中的内存连续?

vector中不会有内存重新分配,几乎可以肯定会有string的重新分配,尽管标准对此没有任何说明。字符串就像一个向量,它将内容与字符串对象本身分开。

否。CCD_ 3将其实际字符串数据存储在单独分配的存储器中(模短字符串优化)。对象的实际大小永远不会改变,并且在编译时是固定的。任何这样的动态大小调整都是使用单独分配的内存或对象层次结构来完成的(例如,集合/映射使用节点树,列表使用节点的双链接列表等)。

是否会进行大规模重新分配,以保持字符串和向量中的内存连续?

向量的元素是连续的,但在每个包含的字符串中,都有一个指向存储文本内容的动态分配存储的指针(假设字符串不是空的,也不短到足以放入固定大小的内部缓冲区——这是一种被称为"短字符串优化"的技术,实现可能但不需要使用)。

现在,对于向量和字符串,了解当前大小(数据的元素数/char)和容量(已经保留的堆的数量,容器可以扩展到其中,而无需分配新的堆区域并在其中移动元素)之间的差异非常重要。

因此,如果现有的容量足够,那么字符串串联就会发生。如果必须增加容量,则更新该字符串指向动态内存的指针,以寻址新分配的更大的堆区域,文本内容将复制到该堆区域,然后释放原始堆区域。

push_back()操作可以导致向量重新分配,但字符串对象"拥有"单独的堆内存块。

如果您想了解具体的实现在做什么,可以在操作前后打印出容器的size()capacity(),以及第一个元素的地址。。。。尽管如此,标准并没有规定重新分配后容量超过大小的数量,因此甚至可能会随着编译器标志/版本、操作系统等而改变

如图所示:

VECTOR:                /-------->[first string's text]...extra capacity...
[ first string object /]
[    second string object   ]
...extra vector capacity...  -->[second string's text]...extra capacity...

string对象是固定大小的。如果包含的字符串不适合字符串实现提供的内部存储(如果有的话),则会单独分配。它与任何其他字符串存储都不连续,至少不是有意的。