【问题标题】:Strange const char* behaviour奇怪的 const char* 行为
【发布时间】:2012-10-20 23:08:22
【问题描述】:

GetTypeName为std::string,代码如下

printf("%#x\n", proto->GetTypeName().c_str());
printf("%s\n", proto->GetTypeName().c_str());
const char *res = proto->GetTypeName().c_str();
printf("%#x\n",res);
printf("%s\n",res);

产生这个输出:

0x90ef78
ValidTypeName
0x90ef78
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■←ЬЬQщZ

地址总是相同的;以下代码(行是交换)

const char *res = proto->GetTypeName().c_str();
printf("%#x\n",res);
printf("%s\n",res);
printf("%#x\n", proto->GetTypeName().c_str());
printf("%s\n", proto->GetTypeName().c_str());

产生这个输出,地址总是不同的:

0x57ef78
  Y
0x580850
ValidTypeName

我做错了什么?

strlen(res)

返回无效的大小,所以我什至不能 strcpy。

【问题讨论】:

    标签: c++ char constants


    【解决方案1】:

    YourGetTypeName 函数返回一个 std::string 并且您正在调用 c_str 以获取指向该字符串中内部数据的指针。

    由于它是临时的,您返回的 std::string 将在语句末尾被删除

    const char *res = proto->GetTypeName().c_str();
    

    但您仍有 res 指向现在已删除的数据。

    编辑:将您的代码更改为:-

    const std::string& res = proto->GetTypeName(); 
    

    并像这样在 printf 中对该字符串调用 .c_str() :-

    printf("%#x\n",res.c_str());
    printf("%s\n",res.c_str());
    

    为引用分配一个临时值会将该临时值的生命周期延长到与引用的生命周期相同...

    更好的是,只需使用 std::string 和 iostream 进行打印,并在不必要时停止使用低级指针:)

    【讨论】:

    • @amaurea:可能,但它有一个缺点:stackoverflow.com/a/134777/166749
    • 有了移动语义,为什么不把返回的字符串存储在一个实际的字符串中呢?然后查看代码的人不必知道 GetTypeName 的签名来验证字符串的生命周期...
    猜你喜欢
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 2017-04-08
    • 1970-01-01
    • 2012-06-01
    • 2017-03-13
    • 1970-01-01
    • 2020-06-25
    相关资源
    最近更新 更多