std :: string :: reserve和end-of-string 0

时间:2015-05-07 20:43:52

标签: c++ dynamic-memory-allocation stdstring

使用std::string::reserve进行预分配时,是否必须明确为终止0添加一个,以避免重新分配和后续复制?

例如,知道长度为5的字符串"Hello"将存储在std::string str中,我是否必须致电str.reserve(6)

如果我正确阅读标准,那么我认为答案应该是。对于reserve,它说

  

在reserve()之后,capacity()大于或等于reserve的参数。

并且capacity依次声明

  

返回:字符串中已分配存储的大小。

但是,我不熟悉标准中配方的细微之处,我想证实我的怀疑。

2 个答案:

答案 0 :(得分:3)

C ++ 11确实指定(或者我在几个地方读过,在n3337文档中实际上找不到这个措辞?)std::string应该存储在这样的这种方式是C型字符串的零终止并不需要重新分配。

当然这是GNU C ++库中的函数_S_create:

template<typename _CharT, typename _Traits, typename _Alloc>
  typename basic_string<_CharT, _Traits, _Alloc>::_Rep*
  basic_string<_CharT, _Traits, _Alloc>::_Rep::
 _S_create(size_type __capacity, size_type __old_capacity,
      const _Alloc& __alloc)
 ....
  // NB: Need an array of char_type[__capacity], plus a terminating
  // null char_type() element, plus enough for the _Rep data structure.
  // Whew. Seemingly so needy, yet so elemental.
  size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);

+ 1用于覆盖终止字符。

然后继续&#34;调整&#34;使用minimum allocationpage_size的一些猜测常数使其更加优化的大小,但始终至少为__size,并始终添加1以腾出空间终止。

要弄清楚它总是&#34;这样做,您必须遵循代码并发现每当需要重新分配字符串时调用_M_clone_M_clone依次调用_S_create。代码不易阅读,因为它的编写遵循标准并且效率高,而不是我们凡人阅读它的目标。

更容易看到c_str没有分配任何内容:

  const _CharT*
  c_str() const _GLIBCXX_NOEXCEPT
  { return _M_data(); }

然后调用:

  _CharT*
  _M_data() const _GLIBCXX_NOEXCEPT
  { return  _M_dataplus._M_p; }

换句话说,只返回指向实际字符串的指针。

答案 1 :(得分:0)

Returns: The size of the allocated storage in the string.

字符串中的分配存储该语句表示字符串应该适合分配的空间。 “字符串”表示“零终止的字符组”,因此也应包含零。