C++ c_str的不当使用

C++ c_str的不当使用,c++,pointers,memory-management,stdstring,C++,Pointers,Memory Management,Stdstring,我有一个定义如下的方法: const std::string returnStringMethod() { std::string myString; // populate myString return myString; } 现在,在来电者中,我正在做这样的事情: const char * ptr = returnStringMethod().c_str(); 正如我所看到的,这返回了一些我没有预料到的被截断的字符串。但是,以下操作很好: std::str

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

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();
有人能帮我理解这里发生了什么吗

附言:我们每周编译一次代码。我在上周提交代码时测试了这个,一切正常。所以,我真的很想知道我在这里遗漏了什么

谢谢, Pavan.

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


当临时值消失时,c_str()返回的字符*将无效。

第一个是未定义的行为,临时
returnStringMethod()
仅在尾部
之前有效,因此内部字符串(由
c_str()
返回)被销毁,因此留下一个悬空指针

第二个版本有效,因为当其作用域结束时,
str
将被销毁,并且其作用域与
ptr
相同(至少在您的示例中是这样)

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

const char * ptr = NULL;
{
    std::string str = returnStringMethod();
    ptr = str.c_str();
}
}
之后,
ptr
不再有效。

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

这意味着
ptr
的值已初始化为指向不再可访问的内存的点


在后一种情况下,如果将
returnStringMethod
的返回值分配给
std::string str
,则将有一个副本,其生存期绑定到当前范围。因此,只要
str
处于活动状态,将
str.c_str()
的值赋给
ptr
是有效的

const char * ptr = returnStringMethod().c_str();
在上面的一行中,函数返回一个临时字符串,该字符串很快就超出了范围。(调用析构函数并释放内存)

在以后的版本中,您将创建字符串的本地副本,从而定义行为

您还可以使用以下命令

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

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

“我们每周编译一次代码”=>可能是主题外的,但为什么?是否有任何东西阻止您编译。。。只要它有意义?不,我想说的是,在关闭更改之前,我上次处理这段代码时,它通过了所有测试。不要复制
c_str()
返回的指针,除非你真的知道自己在做什么,而是直接在c-API调用中使用它。
c_str()
方法旨在作为适配器工作,这也是其奇怪名称的原因。很好@Pavan:取消对悬空指针的引用是未定义的行为。因此,如果幸运的话,它会坏掉,如果不幸运的话,它可能会正常工作。你能告诉我在returnStringMethod().c_str()中临时returnStringMethod()是什么时候被销毁的吗?@Pavan这是未定义的行为,在这种情况下,你本质上是说“立即丢弃它”。@Pavan:有关定义,请参阅。一个好的经验法则是,在创建临时文件的语句被执行后,临时文件立即被销毁。执行以下语句时,临时字符串不再存在。请告诉我函数返回的字符串何时超出范围?请在执行后立即执行。但若您选择了,指针是可以安全使用的。