std::字符串 c_str() 从函数返回后的作用域

std::string c_str() scope after returning from function

本文关键字:返回 函数 作用域 字符串 str std      更新时间:2023-10-16

我在C++/MFC中有下面提到的函数:

CString StringFunc()
{
    std::string abc = "Hello";
    return abc.c_str();
}
int main()
{
    CString Temp = StringFunc();
    Use_Temp(Temp);
}
1.( StringFunc(

( 返回的 abc.c_str(( 指针的生命周期是多少,在 StringFunc(( 返回后,它会安全地复制到变量 'Temp' 吗?

2.( CString Temp = StringFunc(( 是浅拷贝操作还是深拷贝操作?

StringFunc(

( 返回的 abc.c_str(( 指针的生命周期是多少,在 StringFunc(( 返回后,它会安全地复制到变量 'Temp' 吗?

abc将一直有效,直到StringFunc() function返回。是的,将副本返回给 CString 是安全的。

如果返回指向std::string::c_str()的指针,则很危险,例如:

const char* EvilFunc()  // bad, dont' do it
{
   std::string abc = "Hello";
   return abc.c_str();
}
const char* p = EvilFunc(); // p becomes wild pointer when EvilFunc returns

CString Temp = StringFunc(( 是浅拷贝操作还是深拷贝操作?

它是深拷贝。它从const char*构造一个新的CString对象

Ad.1( - 您不是返回字符指针,而是返回从该指针隐式构造的CString实例。 CString 获取传递的字符数据的副本。

Ad.2( - 复制或分配CString会创建深层副本。

是的,内存安全地复制到从函数返回的Cstring对象中。这是一个很深的副本。甚至文档也是这样说的:

因为构造函数将输入数据复制到新分配的 存储时,您应该知道可能会导致内存异常。

1.(:c_str()返回的char const *的生存期只有在控制流在函数StringFunc内,因为字符串变量abc将在该函数结束时被销毁。但是,由于您按值返回 CString,因此从 c_str() 的结果隐式构造一个临时,并且返回该 CString;反过来,这个临时返回值在函数调用出现的表达式末尾(即将函数StringFunc的结果分配给 temp 的整个语句(之前一直有效。因此,StringFunc的结果将安全地复制到 main 中的 Temp 变量中。

2.(这是一个"深"副本,你在那里构建一个新对象!由于按值返回,因此编译器很可能实际上会避免复制任何内容(请参阅返回值优化(,而是简单地构造一个对象。