std :: string(size,' \ 0')和s.resize(size)之间的区别?

时间:2016-07-29 20:38:42

标签: c++ c++14

与std :: vector不同,std :: string不提供采用大小的一元构造函数:

std::string s(size); // ERROR

之间有什么区别:

std::string s(size, '\0');

std::string s;
s.resize(size);

在共同实施方面的表现?

调整大小会将字符串初始化为所有零字符还是会给它们留下未指定的值?

如果全部为零,是否有任何方法可以构造给定大小的字符串,但是将字符保留为未指定的值?

4 个答案:

答案 0 :(得分:4)

存在差异,如s.resize(size);,字符串所需的所有内存都可以立即分配。但是,对于第二个示例,如果char大于为小字符串优化而存储的字符数量,则可能必须执行额外的分配,尽管这是实现定义的,并且肯定不会更高性能在符合标准的C ++ 17实现中。但是,第一个例子更简洁,可能更高效,因此可能更可取。致电'\0'时,所有新字符都将使用string的默认构造函数(即int index = 0; // save original positions var lookup = array.ToDictionary(x => x, x => index++); // sort array Array.Sort(array1); foreach (var item in array) { int originalIndex = lookup[item]; ... array2[originalIndex] } )进行初始化。无法使用未指定的值初始化# change all the country pages RewriteRule ^([^/]*)\.html$ /country.cfm?country=$1 [L] # change all the hotel pages RewriteRule ^([^/]*)\.html$ /hotel.cfm?hotel=$1 [L]

答案 1 :(得分:4)

实际答案是基于实现的,但我很确定$scope.dynamicPopover = { templateUrl: "myPopoverTemplate.html" }; 更快。

std::string s(size, '\0');

根据documentation for std::string

  

1)默认构造函数。构造空字符串(零大小和未指定容量)。

默认构造函数将创建一个具有“未指定容量”的字符串。我的意思是,实现可以自由地确定默认容量,可能在10-15个字符的范围内(完全猜测)。

然后在下一行中,如果std::string s; s.resize(size); 大于当前resize,您将使用新size重新分配内存(size)。这可能不是你想要的!

如果你真的想明确地找到答案,可以在这两种方法上运行一个分析器。

答案 2 :(得分:2)

DeepCoder已有一个很好的答案。

但是对于记录,我想指出字符串(对于向量)有两个不同的概念:

  • size():它是字符串中实际(即有意义)字符的数量。您可以使用resize()对其进行更改(您可以向其提供第二个参数,以说明您希望将哪个字符用作填充符号,如果它不应该是'\0'
  • capacity():它是分配给字符串的字符数。它的尺寸至少可以更大。您可以使用reserve()
  • 增加它

如果您担心分配性能,我认为最好使用容量。真正的字符应保留在字符串中的真实字符中,而不是用于填充字符。

顺便提一下,s.resize(n)更一般地与s.resize(n, char())相同。因此,如果您想在构造时以相同的方式填充它,您可以考虑string s(n, char())。但是只要你不使用basic_string<T> T与字符不同,你的'\ 0'就可以了。

答案 3 :(得分:1)

调整大小不会使元素未初始化。根据文件:http://en.cppreference.com/w/cpp/string/basic_string/resize

s.resize(size)将对每个附加字符进行值初始化。这将导致调整大小的字符串的每个元素初始化为'\0'

您必须衡量特定C ++实现的性能差异,才能真正确定是否存在有价值的差异。

在查看由Visual C ++生成的机器进行优化构建之后,我可以告诉您这两个版本的代码量是相似的。对于我而言,调整大小()版本的测量 更快 似乎是反直觉的。不过,您应该检查自己的编译器和标准库。