c_str使用不当

时间:2014-05-26 11:54:33

标签: c++ pointers memory-management stdstring

我有一个定义如下的方法:

const std::string returnStringMethod()
{
    std::string myString;

    // populate myString

    return myString;
}

现在,在来电者中,我正在做这样的事情:

const char * ptr = returnStringMethod().c_str(); 

正如我所看到的,这会返回一些我没想到的截断字符串。但是,以下工作正常:

std::string str = returnStringMethod();
const char * ptr = str.c_str();

有人可以帮我理解这里发生的事情吗?

PS:我们每周构建一次代码。我上周提交代码时测试了这个,事情还不错。所以,我真的想知道我在这里可能会缺少什么。

感谢, 帕。

4 个答案:

答案 0 :(得分:9)

第一个是未定义的行为,临时returnStringMethod()仅在尾随;之前有效,因此内部字符串(由c_str()返回)被销毁,所以你离开了一个悬垂的指针。

第二个版本是有效的,因为str在其范围结束时将被销毁,其范围与ptr相同(至少在您的示例中)。

例如,以下内容也是错误的:

const char * ptr = NULL;
{
    std::string str = returnStringMethod();
    ptr = str.c_str();
}

}之后,ptr不再有效。

答案 1 :(得分:3)

returnStringMethod返回值是一个临时字符串,其生命周期与表达式本身绑定;这意味着,在std::string初始化c_str后,您ptr上的const char * ptr = returnStringMethod ().c_str ()将被销毁。

这样做的含义是ptr已初始化的值,指向不再可访问的内存。


在后一种情况下,将returnStringMethod的返回值分配给std::string str,您将获得一个生命周期绑定到当前范围的副本。将str.c_str ()的值分配给ptr,只要str有效,就会有效。

答案 2 :(得分:3)

const char * ptr = returnStringMethod().c_str();

在上面一行中,一个临时字符串由函数返回,该函数很快就会超出范围。 (并且调用析构函数并释放内存)

在更高版本中,您可以创建字符串的本地副本,从而定义行为。

您还可以使用以下

const std::string &str = returnStringMethod();
const char * ptr = str.c_str();

使用const引用会延长临时变量的生命周期,直到引用在范围内,并且不会有(明确的)不需要的副本。

答案 3 :(得分:1)

您正在返回(临时)副本以及执行c_str()的位置。

当临时消失时,c_str()返回的char *变为无效。