在C中,有一个很好的构造来创建一个具有更多分配空间的c-string:
char str[6] = "Hi"; // [H,i,0,0,0,0]
我认为我可以使用({3}}的(4)版本来做同样的事情,但参考文献说
如果s未指向CharT的至少count个元素的数组,则行为未定义。
因此使用
是不安全的std::string("Hi", 6);
有没有办法在没有额外副本和重新分配的情况下创建这样的std :: string?
答案 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
是一个运行时生物,它必须分配一些运行时内存:
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来重新分配。