为什么在返回字符串的函数上调用c_str()不起作用?

时间:2014-12-23 20:17:02

标签: c++ string

我有一个返回字符串的函数。但是,当我调用它并对其执行c_str()以将其转换为const char *时,它仅在我首先将其存储到另一个字符串时才起作用。如果我直接从函数中调用c_str(),它会将垃圾值存储在const char *中。

为什么会这样?感觉我在这里缺少一些非常基本的东西......

string str = SomeFunction();
const char* strConverted = str.c_str(); // strConverted stores the value of the string properly
const char* charArray= SomeFunction().c_str(); // charArray stores garbage value

static string SomeFunction()
{
    string str;
    // does some string stuff
    return str;
}

4 个答案:

答案 0 :(得分:19)

SomeFunction().c_str()为您提供指向临时(str正文中的自动变量SomeFunction)的指针。与引用不同,在这种情况下,临时工的生命周期不会延长,最终charArray是一个悬空指针,解释了当您尝试使用charArray时稍后看到的垃圾值。

另一方面,当你做

string str_copy = SomeFunction();

str_copySomeFunction()的返回值的副本。现在调用c_str()会为您提供指向有效数据的指针。

答案 1 :(得分:2)

函数返回的值对象是临时的。 c_str()的结果仅在临时的生命周期内有效。在大多数情况下,临时的生命周期是完整表达式的结尾,通常是分号。

const char *p = SomeFunction();
printf("%s\n", p); // p points to invalid memory here.

解决方法是确保在完整表达式结束之前使用c_str()的结果。

#include <cstring>

char *strdup(const char *src_str) noexcept {
    char *new_str = new char[std::strlen(src_str) + 1];
    std::strcpy(new_str, src_str);
    return new_str;
}

const char *p = strdup(SomeFunction.c_str());

请注意,strdup是POSIX函数,因此如果您是支持POSIX的平台,那么它已经存在。

答案 2 :(得分:0)

  1. 方法string str中的“SomeFunction()”是SomeFunction()中的局部变量,只能在SomeFunction()范围内生存;

    < / LI>
  2. 由于方法SomeFunction()的返回类型是字符串,而不是字符串的引用,在“return str;”之后,SomeFunction()将返回值{的副本{1}},在str调用后,将作为临时值存储在某个内存位置,临时值将立即销毁;

  3. SomeFunction()”会将返回的临时值string str = SomeFunction();存储到字符串SomeFunction(),实际上是该值的副本并存储到str,在“strstr的调用完成后,SomeFunction()的生命周期大于;的生命周期,并且返回的临时值会立即销毁,内存将由系统回收,但此值的副本仍存储在SomeFunction()中。这就是为什么“str”可以获得正确的值,实际上const char* strConverted = str.c_str();返回了c_str()的初始元素的指针(str的第一个元素内存地址指向的字符串值),而不是返回的临时值str;

  4. SomeFunction()”不同,“const char* charArray= SomeFunction().c_str();”将返回返回临时值的初始元素的指针(返回的临时字符串值的第一个元素内存地址),但是在调用SomeFunction().c_str()之后,返回的临时值被销毁,并且系统重用该内存地址,SomeFunction()可以获取该内存地址的值,但不能获得您期望的值;

答案 3 :(得分:-3)

使用strcpy将字符串复制到本地定义的数组,您的代码将正常工作。