我只想使用 std::string 来创建一个动态缓冲区,而不是使用索引遍历它。 resize() 是唯一实际分配缓冲区的函数吗?
我尝试了 reserve() 但是当我尝试通过索引访问字符串时,它断言。此外,当字符串的默认容量似乎是 15 个字节(在我的情况下)但如果我仍然无法以 my_string[1]
的形式访问它。
那么字符串的容量不是实际的缓冲区吗?另外reserve() 也不分配实际的缓冲区?
string my_string;
// I want my string to have 20 bytes long buffer
my_string.reserve( 20 );
int i = 0;
for ( parsing_something_else_loop )
{
char ch = <business_logic>;
// store the character in
my_string[i++] = ch; // this crashes
}
如果我使用 resize() 而不是 reserve() 就可以了。字符串有容量但不能用[]真正访问它是怎么回事?这不就是要保留()大小以便您可以访问它吗?
插件 作为对答案的回应,我想问 STL 的人,当 resize() 完全相同并且还初始化字符串时,为什么有人会使用 reserve() ?我不得不说我不太欣赏这种情况下的性能论点。除了reserve() 所做的之外,resize() 所做的所有事情就是它只是初始化缓冲区,我们知道无论如何这样做总是很好的。我们可以在岛上投票 reserve() 吗?
最佳答案
Isn't that the point to reserve() size so you can access it?
不,这就是 resize()
的意义所在。
reserve()
只提供足够的空间,以便将来导致大小增加的调用(例如调用 push_back()
)更有效。
从您的用例看来,您应该改用 .push_back()
。
my_string.reserve( 20 );
for ( parsing_something_else_loop )
{
char ch = <business_logic>;
my_string.push_back(ch);
}
How is it that the string has the capacity but can't really access it with []?
调用 .reserve()
就像炸毁山脉给你一些自由的土地。空闲土地的数量是.capacity()
。土地在那里,但这并不意味着你可以在那里生活。你必须建房子才能搬进来。房子的数量是 .size()
(= .length()
)。
假设你正在 build 一座城市,但是在 build 了第 50 宫之后你发现土地不够用,所以你需要另找一个足够大的地方来容纳第 51 宫,然后将整个人口迁移到那里。这是非常低效的。如果您知道需要预先 build 1000 座房屋,那么您可以调用
my_string.reserve(1000);
获得足够的土地来 build 1000 座房屋,然后你打电话
my_string.push_back(ch);
用 ch
分配到这个位置来 build 房子。容量是1000,但是size还是1。你可能不会说
my_string[16] = 'c';
因为 16 号房子还不存在。你可以打电话
my_string.resize(20);
一口气建好#0~#19的房子,这就是为什么
my_string[i++] = ch;
工作正常(只要 0 ≤ i ≤ 19)。
另见 http://en.wikipedia.org/wiki/Dynamic_array .
关于您的附加问题,
.resize()
不能完全替换 .reserve()
,因为 (1) 你并不总是需要用完所有分配的空间,以及 (2)默认构造 + 复制分配是一个两步过程,这可能比直接构造(尤其是对于大型对象)花费更多时间,即
#include <vector>
#include <unistd.h>
struct SlowObject
{
SlowObject() { sleep(1); }
SlowObject(const SlowObject& other) { sleep(1); }
SlowObject& operator=(const SlowObject& other) { sleep(1); return *this; }
};
int main()
{
std::vector<SlowObject> my_vector;
my_vector.resize(3);
for (int i = 0; i < 3; ++ i)
my_vector[i] = SlowObject();
return 0;
}
会浪费你至少 9 秒的时间来运行,而
int main()
{
std::vector<SlowObject> my_vector;
my_vector.reserve(3);
for (int i = 0; i < 3; ++ i)
my_vector.push_back(SlowObject());
return 0;
}
仅浪费 6 秒。
std::string
这里只复制std::vector
的接口(interface)。
关于c++ - std::strings 的容量()、保留()和调整大小()函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9521629/