如果我调整大小,然后按如下方式分配std :: string
std::string str;
str.resize(4);
str[1] = 'A'; // No problem
应该没有问题,但如果我保留然后分配
std::string str;
str.reserve(4);
str[1] = 'A'; // ?
会有问题吗?我读到元素没有初始化,并且大小没有增加。用[]运算符赋值给元素是否有意义?
答案 0 :(得分:3)
通过为至少整个文件大小的字符串保留容量,我们尝试避免每次插入新字符使其长度超过其容量时对象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]
。