2014-10-01 39 views
0

我有一个非常简单的代码片段:COUT的char *是不同

#include <iostream> 

using namespace std; 

string getString() { 
    return "test"; 
} 

int main(){ 
    const char* testString = getString().c_str(); 
    cout << "string 1:" << testString << endl; 
    string dummy[] = {"1","2","0"}; 
    cout << "string 2:" << testString << endl; 
    return 0; 
} 

我想到两人COUTS将打印相同的输出,但我得到的输出是

string 1:test 
string 2:1 

任何人都可以解释为什么会发生这种情况?另外,我观察到两件事:

1)如果dummy[]int类型,那么它们将打印出与预期完全相同的字符串test

2)如果我首先将getString()分配给一个字符串变量,那么将第一行改为const char* testString = variable.c_str();,然后它们会按照预期输出相同的字符串。

回答

4

行为未定义。

const char* testString = getString().c_str(); 

getString返回一个临时对象,当评估完成时它将被销毁。作为结果。 testString指向被破坏对象的内部,导致未定义的行为。

实际上,可能会发生数据仍然在该地址一段时间,这就是为什么第一个cout给出错误的正确性。

+0

true,没有进行内存分配来返回字符串。 – Elod 2014-10-01 16:40:17

+0

@Elod:内存分配给临时;但是暂时的,它在这条线的末尾被摧毁了。 – 2014-10-01 16:42:16

1

您可以设置指针,指向该声明

const char* testString = getString().c_str(); 

所以该方案已不确定的行为后删除临时对象。

正确的代码可能看起来像

const char * getString() { 
    return "test"; 
} 

int main(){ 
    const char* testString = getString(); 
//... 

,因为字面字符串具有静态存储持续时间。

+0

修复了这个简单的例子;但是当你需要返回一个'string'时并没有帮助。 – 2014-10-01 16:45:45

+0

@Mike Seymour这是另一个问题。你可以自己问问。 – 2014-10-01 16:47:34

0

当您从管理该字符串的内存的字符串对象中获取低级别字符指针时,该指针仅适用于对象处于活动状态的特定

实际上它比这更窄。如果您在字符串对象上调用任何非const成员,这意味着即使对象析构函数未运行,也不能相信您从之前调用c_str()的任何值仍然很好。

#include <iostream> 

using namespace std; 

string getString() { 
    return "test"; 
} 

int main(){ 
    string testString = getString(); 
    const char * testCstring = testString.c_str(); 
    cout << "string 1:" << testCstring << endl; 
    string dummy[] = {"1","2","0"}; 
    cout << "string 2:" << testCString << endl; 
    return 0; 
} 

这是合法的,但不从c_str()所做的任何修改改变你 - 或有被摧毁该字符串得到它后的字符串依靠指针。

另外请注意,没有必要从字符串中获取char *以输出它。开始思考使用字符串对象,不要去char *,除非你有充分的理由。

相关问题