返回本地C-字符串函数与C++字符串返回值

问题描述:

下面这段代码编译并没有错误,并与预期输出运行:返回本地C-字符串函数与C++字符串返回值

#include <string> 
#include <iostream> 
using namespace std; 

string getString() 
{ 
    char s[] = "Hello world!"; 
    return s; 
} 

int main() 
{ 
    cout << getString() << endl; 
} 

我的问题是,这将始终工作?通常如果你返回一个在本地声明的C字符串,你可能会遇到一些未定义的行为,但在这种情况下,它仍然是一个问题,因为它是通过字符串构造函数运行的,并且(大概)被复制到动态内存中?

+0

将std :: string添加到标准库的主要原因之一 - 它可以用作嵌入类型,比如'int'和'double',所以是的,返回'std :: string'值。 – Slava

+1

你知不知道string litterals有静态存储时间:[cpp-ref](http://en.cppreference.com/w/cpp/language/string_literal)。因此,如果你的c-string只是指向一个字符串类似于'const char * s =“Hello World”''的字符串,你可以安全地从你的函数中返回它,因为s是一个指向具有静态存储持续时间的对象的指针。这就是为什么'std :: except :: what()'或'type_info :: name()'返回一个c字符串 – Oliv

+0

@Oliv这是一个整洁的事实,但这只是一个例子,在我真正的程序中,C字符串是在运行时创建 –

return s; 

该行等同于:

return std::string(s); 

这将使复制字符串的,所以它的罚款。

参考:http://en.cppreference.com/w/cpp/string/basic_string/basic_string(构造#5)

构造具有与所述空终止字符串的副本初始化内容的字符串由s指向。

编辑:一个更多的细节。您提到

复制到动态内存中?

而答案也许可能是,这并不重要。

std::string提供的语义朝着这个不规范,它只是保证了它可以被复制/移动的周围,以一致的事项进行访问。它如何达到这一点取决于图书馆的实施者。

事实上,std::string使用一些流行的实现称为“小号商场小号特林Ø ptimization”。字符串对象本身存储了某些长度以下的字符串。

+0

返回的临时'std :: string'对象是从数组's'构造的(不是拷贝!)。 – Buster

+1

我想你是曲解了,'std :: string'的构造函数复制's'指向的字符串的内容。 's'仍然是一个字符串,一个c字符串,但是仍然是一个字符串。 – Frank

+0

是的,够公平的。不可否认的是,“字符串的_copy_”被创建,意味着字符串的字节将被复制。 – Buster