为具有 C++ 字符串返回值的函数返回本地 C 字符串
Posted
技术标签:
【中文标题】为具有 C++ 字符串返回值的函数返回本地 C 字符串【英文标题】:Return a local C-string for function with C++ string return value 【发布时间】:2017-08-01 17:20:10 【问题描述】:以下代码编译并运行,没有错误并具有预期的输出:
#include <string>
#include <iostream>
using namespace std;
string getString()
char s[] = "Hello world!";
return s;
int main()
cout << getString() << endl;
我的问题是,这会一直有效吗?通常,如果您返回一个在本地声明的 C 字符串,您可能会遇到一些未定义的行为,但在这种情况下,这仍然是一个问题,因为它是通过字符串构造函数运行并(可能)复制到动态内存中的?
【问题讨论】:
std::string
添加到标准库的主要原因之一 - 它可以用作像 int
和 double
这样的嵌入式类型,所以可以按值返回 std::string
.
你知道字符串litterals有静态存储持续时间:cpp-ref。因此,如果您的 c 字符串仅指向 const char* s="Hello World"
中的字符串文字,您可以安全地从函数中返回它,因为 s 是指向具有静态存储持续时间的对象的指针。这就是 std::except::what()
或 type_info::name()
返回 c 字符串的原因
@Oliv 这是一个很好的事实,但这只是一个例子,在我的真实程序中,C 字符串是在运行时创建的
【参考方案1】:
return s;
那一行相当于:
return std::string(s);
这将制作字符串的副本,所以没关系。
参考:http://en.cppreference.com/w/cpp/string/basic_string/basic_string(构造函数#5)
用 s 指向的以空字符结尾的字符串的副本初始化内容构造字符串。
编辑:更多细节。你提到
复制到动态内存中?
而答案可能是,也许,这并不重要。
std::string
提供的语义对此没有任何规范,它只是保证它可以被复制/移动并以一致的方式访问。如何实现这一点取决于库实现者。
事实上,std::string
的流行实现使用称为“Small String O优化”的东西。特定长度以下的字符串存储在字符串对象本身中。
【讨论】:
返回的临时std::string
对象是从数组 s
构造(而不是复制!)。
我想你是误解了,std::string
的构造函数复制了s
指向的字符串的内容。 s
仍然是一个字符串,一个 c 字符串,但仍然是一个字符串。
是的,很公平。不可否认的是,“字符串的副本”是被复制的,因为字符串的字节将被复制。以上是关于为具有 C++ 字符串返回值的函数返回本地 C 字符串的主要内容,如果未能解决你的问题,请参考以下文章