保留并分配给一个std::string

3
如果我按照以下方式调整大小并分配std::string
std::string str;
str.resize(4);
str[1] = 'A'; // No problem

理论上不应该有问题,但如果我预留了然后再分配

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

会有问题吗?我读到元素被未初始化并且大小没有增加。使用[]操作符给一个元素赋值有意义吗?


4
第二个没有意义,是未定义的行为。 - user2249683
你能详细说明一下你的回答吗?我仍然不理解出了什么问题。 - Albert
2
你已经回答了自己的问题:“我读到元素没有被初始化,大小也没有增加。” - Austin Brunkhorst
3个回答

4

来自cplusplus

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

reserve不会增加字符串的大小,只是指出在进行重新分配时需要增加多少容量。


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,以下是未定义行为:

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

0

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

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

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接