【问题标题】:What's the scope of this string?这个字符串的范围是什么?
【发布时间】:2012-11-08 14:18:06
【问题描述】:

如果我有以下代码:

{
    UnicodeString sFish = L"FISH";
    char *szFish = AnsiString(sFish).c_str();

    CallFunc(szFish);
}

那么创建的临时AnsiString 的范围是什么,szFish 指向有效数据多长时间? CallFunc 函数仍然有效吗?

它的作用域是只持续一行,还是持续整个块?

【问题讨论】:

  • 不熟悉UnicodeStringAnsiString,但字符串必须至少持续到块结束。

标签: c++ c++builder c++builder-xe


【解决方案1】:

szFish 在调用CallFunc() 之前是无效的,因为AnsiString 是一个立即被销毁的临时对象,而szFish 指向它的内部缓冲区,该缓冲区刚刚被删除。

确保AnsiString 实例对于CallFunc() 的调用有效。例如:

CallFunc(AnsiString(sFish).c_str());

【讨论】:

    【解决方案2】:

    我会替换:

    char *szFish = AnsiString(sFish).c_str();
    

    与:

    AnsiString as(sFish);
    char *szFish = as.c_str();
    

    我不知道AnsiString 类,但在您的代码中,它的析构函数会在您调用CallFunc() 之前触发,并且很可能会释放您使用*szFish 指向的字符串。当您用堆栈上的“命名”对象替换临时对象时,它的生命周期将延长到定义它的块的末尾。

    【讨论】:

    • 是的,我已经这样解决了。我想 100% 确定原因。
    • 这是一个很好的解释(我相信来自 C++ 标准)临时对象的生命周期stackoverflow.com/questions/4214153/lifetime-of-temporaries $12.2/3-“临时对象被销毁作为评估完整表达式的最后一步(1.9) (词法上)包含创建它们的点。即使评估以抛出异常结束也是如此。"
    【解决方案3】:

    C++11 标准 $12.2.3 说:

    当一个实现引入一个类的临时对象时 有一个非平凡的构造函数(12.1,12.8),它应确保 为临时对象调用构造函数。同样, 应调用析构函数以获取具有非平凡的临时 析构函数(12.4)。 临时对象作为最后一步被销毁 评估(词汇上)包含的完整表达式(1.9) 它们的创建点。即使该评估也是如此 以抛出异常结束。价值计算和副作用 销毁临时对象仅与 全表达式,没有任何特定的子表达式。

    (强调我的)

    对此还有一些额外的警告,但它们不适用于这种情况。在您的情况下,完整的表达式是该语句的指示部分:

    char *szFish = AnsiString(sFish).c_str();
    //             ^^^^^^^^^^^^^^^^^^^^^^^^^
    

    因此,在分配szFish 的瞬间,将调用临时对象的析构函数(即AnsiString(sFish)),并释放其内部内存表示(c_str() 指向的位置)。因此,szFish 将立即成为一个悬空指针,任何访问都将失败。

    你可以通过说来解决这个问题

    CallFunc(AnsiString(sFish).c_str());
    

    相反,就像这里一样,临时将在 full 表达式之后(即在 ; 处)被销毁(再次),CallFunc 将能够读取原始字符串.

    【讨论】:

      【解决方案4】:

      在这种情况下,AnsiString 的范围是“从调用之前到c_str(),直到之后。”

      这样想可能会有所帮助:

      char *szFish; 
      
      { 
          AnsiString tmpString(sFish); 
          szFish = tmpString.c_str(); 
      }
      

      【讨论】:

        猜你喜欢
        • 2012-03-17
        • 1970-01-01
        • 2018-05-01
        • 2015-11-09
        • 1970-01-01
        • 2011-12-05
        • 1970-01-01
        • 2020-04-15
        • 2011-12-06
        相关资源
        最近更新 更多