使用std::string::reserve
进行预分配时,是否必须明确为终止0
添加一个,以避免重新分配和后续复制?
例如,知道长度为5的字符串"Hello"
将存储在std::string str
中,我是否必须致电str.reserve(6)
?
如果我正确阅读标准,那么我认为答案应该是是。对于reserve
,它说
在reserve()之后,capacity()大于或等于reserve的参数。
并且capacity
依次声明
但是,我不熟悉标准中配方的细微之处,我想证实我的怀疑。返回:字符串中已分配存储的大小。
答案 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 allocation
和page_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.
字符串中的分配存储该语句表示字符串应该适合分配的空间。 “字符串”表示“零终止的字符组”,因此也应包含零。