c++ - std::strings 的容量()、保留()和调整大小()函数

标签 c++ string stl

我只想使用 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/

相关文章:

c++ - 在类中初始化动态数组的函数

C++ 返回字符串导致 free() : invalid pointer error

python - 将字符串封闭列表转换为列表

javascript - 如何 chop jQuery 中的字符串?

C++ 二维数组函数

c++ - 用 stringstream 解析 float - 精度?

C++ 从 std::vector 膨胀 zlib

c++ - map 运算符 < 条件 - 无效比较器

c++ - STL 容器中的自定义析构函数

pointers - vector <list <T >>是否保证元素地址保持不变?