保留然后分配给std :: string

时间:2015-05-29 17:08:17

标签: c++

如果我调整大小,然后按如下方式分配std :: string

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

应该没有问题,但如果我保留然后分配

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

会有问题吗?我读到元素没有初始化,并且大小没有增加。用[]运算符赋值给元素是否有意义?

3 个答案:

答案 0 :(得分:3)

来自cplusplus

  

通过为至少整个文件大小的字符串保留容量,我们尝试避免每次插入新字符使其长度超过其容量时对象str可能遭受的所有自动重新分配。 / p>

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

答案 1 :(得分:1)

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, '\0');

虽然现在是合法的

s[0] = 'a';

以下是非感性的,因为它会生成无效的c字符串;第一个字节是0,因此是终结符。

std::string s;
s.resize(1000, '\0'); // 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.

答案 2 :(得分:0)

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

我可能会使用这样的东西:

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

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