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

时间:2017-10-22 10:20:57

标签: c++ string constructor

在C中,有一个很好的构造来创建一个具有更多分配空间的c-string:

char str[6] = "Hi";  // [H,i,0,0,0,0]

我认为我可以使用({3}}的(4)版本来做同样的事情,但参考文献说

  

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

因此使用

是不安全的
std::string("Hi", 6);

有没有办法在没有额外副本和重新分配的情况下创建这样的std :: string?

2 个答案:

答案 0 :(得分:4)

<强>理论值:

旧版c字符串

请考虑以下代码段:

int x[10];

void method() {
     int y[10];
}

第一个声明,int x [10],使用静态存储持续时间,由cppreference定义为:&#34;对象的存储在程序开始时分配,并在程序解除分配时结束。只存在一个对象实例。在命名空间范围内声明的所有对象(包括全局命名空间)都具有此存储持续时间,以及使用static或extern声明的持续时间。&#34;

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

  

静态存储持续时间。程序开始时分配对象的存储空间,程序结束时取消分配对象的存储空间。

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

第二个,即[10],使用自动存储持续时间,由cppreference定义为:&#34;对象在封闭代码块的开头分配,并在结束。除了声明为static,extern或thread_local的那些外,所有本地对象都有此存储持续时间。&#34;

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

的std :: string

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

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

<强>实践

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

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

std::string str;
str.reserve(6);
str.append("Hi");

选项2:首先构建,然后保留

std::string str("Hi");
str.reserve(6);

答案 1 :(得分:0)

要确保最多一次运行时分配,您可以编写:

std::string str("Hi\0\0\0", 6);
str.resize(2);

然而,在实践中,许多字符串实现使用Small String Optimization,如果字符串是&#34; short&#34;则不会进行分配。 (在该线程上建议最大为16)。所以实际上你不会通过在大小2处开始关闭字符串然后增加到6来重新分配。