如何创建具有预定义值和分配空间的字符串?

Jan*_*roň 4 c++ string constructor

在 C 中,有一个很好的构造来创建具有更多分配空间的 C 字符串:

char str[6] = "Hi";  // [H,i,0,0,0,0]
Run Code Online (Sandbox Code Playgroud)

我以为我可以使用 (4) 版本的字符串构造函数做同样的事情,但参考文献说

如果 s 未指向 CharT 的至少 count 个元素的数组,则行为未定义。

所以使用起来并不安全

std::string("Hi", 6);
Run Code Online (Sandbox Code Playgroud)

有没有办法创建这样的 std::string 而不需要额外的副本和重新分配?

Dan*_*man 5

理论:

传统 C 弦

考虑以下片段:

int x[10];

void method() {
     int y[10];
}
Run Code Online (Sandbox Code Playgroud)

第一个声明 int x[10] 使用静态存储持续时间,由 cppreference 定义为:“对象的存储在程序开始时分配,在程序结束时释放。该对象仅存在一个实例。声明的所有对象在命名空间范围(包括全局命名空间)具有此存储持续时间,加上那些用 static 或 extern 声明的存储持续时间。”

在这种情况下,分配在程序开始时发生,并在程序结束时释放。来自cppreference.com

静态存储时间。对象的存储空间在程序开始时分配,并在程序结束时释放。

非正式地,它是实现定义的。但是,由于这些字符串永远不会更改,因此它们存储在可执行文件的只读内存段 (.BSS/.DATA) 中,并且仅在运行时引用。

第二个,int y[10],使用自动存储持续时间,由 cppreference 定义为:“对象在封闭代码块的开头分配并在末尾释放。所有本地对象都有此存储持续时间,除了那些声明的对象之外静态、外部或 thread_local。”

在这种情况下,有一个非常简单的分配,在大多数情况下就像移动堆栈指针一样简单。

标准::字符串

std::string另一方面,A是一个运行时生物,它必须分配一些运行时内存:

  • 对于较小的字符串,std::string 有一个大小恒定的内部缓冲区,并且能够存储小字符串(将其视为成员char buffer[N]
  • 对于较大的字符串,它执行动态分配。

实践

你可以使用reserve(). 此方法确保底层缓冲区可以容纳至少 N 个字符。

选项 1:先保留,然后追加

std::string str;
str.reserve(6);
str.append("Hi");
Run Code Online (Sandbox Code Playgroud)

方案二:先建设,后保留

std::string str("Hi");
str.reserve(6);
Run Code Online (Sandbox Code Playgroud)