保留,然后赋值给std::string

reserve and then assign to a std::string

本文关键字:std string 赋值 然后 保留      更新时间:2023-10-16

如果我调整size,然后分配std::string,如下所示

std::string str;
str.resize(4);
str[1] = 'A'; // No problem

应该不会有问题,但是如果我保留然后赋值

std::string str;
str.reserve(4);
str[1] = 'A'; // ?

会有问题吗?我读到元素没有初始化,大小也没有增加。那么用[]操作符赋值给一个元素有意义吗?

from cplusplus

通过为字符串保留至少等于整个文件大小的容量,我们试图避免每次插入新字符会使对象str的长度超过其容量而导致的自动重新分配。

reserve不增加字符串的大小,只是说明下次重新分配时需要增加多少。

std::string::reserve分配但不初始化内存(http://www.cplusplus.com/reference/string/string/reserve/);也就是说,它请求capacity。但不影响size,因此

std::string s;
s.reserve(1000);
s[0] = 'a';

是非法的,因为字符串的长度为零,所以s[0]访问超出当前字符串的末端。

根据规范,resize可选地接受一个填充字符参数:

std::string s;
s.resize(1000, ' ');
如果省略

,则用空字节填充字符串,相当于

s.resize(1000, '');

而现在

是合法的
s[0] = 'a';
下面的

是无意义的,因为它生成一个无效的c-string;第一个字节为0,因此为终止符。

std::string s;
s.resize(1000, ''); // or s.resize(1000);
s[1] = 'a'; // s[0] is 0 and thus as a c-string [1] is beyond eos.

std::string::operator[]不需要观察或检查size,以下是UB:

std::string s;
s.resize(8);
char a = s[9];  // beyond length, may crash, may return garbage.

reserve只保留字符串扩展的空间。它不会而不是将字符串扩展到该空间。尝试在字符串展开之前使用元素,使该元素成为字符串的一部分,将导致未定义行为。

我可能会这样写:

str.reserve(4);
str.push_back('A');

注意,这将str[0]设置为A,而不是str[1]。要设置str[1]中的值,还必须(以某种方式)初始化str[0]