【问题标题】:std::string c_str() scope after returning from function从函数返回后的 std::string c_str() 范围
【发布时间】:2013-10-15 04:14:56
【问题描述】:

我在 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() 是浅拷贝操作还是深拷贝?

【问题讨论】:

  • 你的代码根本没有缩进,你使用了void main。我编辑了问题以解决这些问题。

标签: c++ visual-studio-2010 visual-c++ mfc object-lifetime


【解决方案1】:

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 对象

【讨论】:

  • 你如何让 EvilFunc 成为一个好的?我有同样的场景,一个覆盖工具在 c_str() 返回时报告了一些问题。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    是的,内存被安全地复制到函数返回的Cstring 对象中。这是一个深拷贝。 Even the documentation says so:

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

    【讨论】:

      【解决方案4】:

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

      2.) 这是一个“深”副本,您在那里构造一个新对象!由于您按值返回,因此您的编译器实际上很可能会避免复制任何内容(请参阅Return-Value optimization),而是会简单地构造一个对象。

      【讨论】:

        猜你喜欢
        • 2021-06-30
        • 2017-03-26
        • 2011-02-09
        • 2018-11-22
        • 1970-01-01
        • 2022-10-27
        • 1970-01-01
        • 1970-01-01
        • 2020-02-17
        相关资源
        最近更新 更多