如果字符串大小可变,如何保留字符串向量?

Ban*_*Man 1 c++ string vector reserved

我想string向 a 添加许多 s vector,根据我的发现,reserve()在此之前调用会更有效。对于a vectorof ints,这是有道理的,因为int是4个字节,所以调用reserve(10)显然保留了40个字节。我知道字符串的数量,大约是60000。我应该打电话吗vector.reserve(60000)?编译器如何知道我的strings 的大小,因为它不知道这些strings 的长度是 5 还是 500?

lor*_*rro 6

编译器不知道字符串的大小,它知道std::string对象的大小。std::string 现在,对象的大小不依赖于字符串的大小。那是因为 - 大多数时候 [1] -std::string将在堆上分配,因此对象本身只是一个指针和长度。

这也意味着,当您保留向量时,您还没有为字符串保留内存。然而,这并不总是一个问题。std::string来自某个地方:如果您收到的字符串是函数的返回值(即,您通过值获得它们),则已经为该字符串分配了内存(在返回值中)。因此,egstd::swap()可以帮助您加快用结果填充数组的速度。

然而,如果您使用传递引用来填充它,那么被调用者将执行导致分配的操作。在这种情况下,您可能希望循环遍历向量并保留每个字符串:

std::vector<std::string> v;
v.reserve(60000); // expected number of strings
for (auto& s : v) {
    s.reserve(500); // expected/max. size of strings
}
Run Code Online (Sandbox Code Playgroud)

[1] 可能会出现这样的情况:std::string实际上有一个小的、固定大小的缓冲区用于排序字符串,因此当字符串比该缓冲区长时,仅在堆上分配。