c++ - std::string::reserve 和字符串结尾 0

标签 c++ dynamic-memory-allocation stdstring

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

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

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

After reserve(), capacity() is greater or equal to the argument of reserve.

对于 capacity 依次声明

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

不过,我不太熟悉标准中公式的微妙之处,我想证实我的怀疑。

最佳答案

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 用于覆盖终止符。

然后它继续“调整”大小以使其更优化,使用一些猜测的最小分配page_size常量,但它始终是 AT最小 __size,并且总是添加 1 为终止腾出空间。

要弄清楚它“总是”这样做,您必须遵循代码并发现每当需要重新分配字符串时都会调用 _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; }

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

关于c++ - std::string::reserve 和字符串结尾 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30111288/

相关文章:

c++ - 如何开发适用于 Symbian OS V2 的应用程序?

c++ - 使用 libgtkhtml c c++ 显示网页

c - 如果一个 C 函数被调用两次,它会创建一个在函数中声明的变量两次吗?

c++ - 编译时字符串赋值用于运行时识别

c++ - 使用 apt 安装在 Ubuntu 20.04 LTS 上找不到 c++ boost 头文件

C++ 字符串声明

C++ 流如何为输入分配空间?

c++ - 不正常的退出会破坏 C++ 内存分配器吗?

c++ - std::string 附加线程安全天真的解决方案?

C++获取字符串数组的大小