c_str使用不当

问题描述 投票:0回答:4

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

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:我们每周构建一次代码。我上周提交代码时对此进行了测试,一切都很好。所以,我真的很想知道我在这里可能会错过什么。

谢谢, 帕万。

c++ pointers memory-management stdstring temporary-objects
4个回答
9
投票

第一个是未定义的行为,临时

returnStringMethod()
仅在尾随
;
之前有效,因此内部字符串(由
c_str()
返回)被销毁,因此留下了一个悬空指针。

第二个版本是有效的,因为

str
将在其范围结束时被销毁,并且其范围与
ptr
相同(至少在您的示例中)。

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

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

}
之后,
ptr
不再有效。


4
投票
const char * ptr = returnStringMethod().c_str();

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

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

您还可以使用以下

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

使用 const 引用会延长临时变量的寿命,直到引用在范围内并且不会有(显式的)不需要的副本。


3
投票

returnStringMethod

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

这意味着

ptr
已初始化的值指向不再可访问的内存。


在后一种情况下,将

returnStringMethod
的返回值分配给
std::string str
,您将拥有一个其生命周期绑定到当前作用域的副本。因此,只要
str.c_str ()
还活着,将
ptr
的值分配给
str
就有效。


1
投票

您将返回一个(临时)副本,这就是您执行 c_str() 的地方。

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

© www.soinside.com 2019 - 2024. All rights reserved.