【问题标题】:very strange output with const ref initialise带有 const ref 初始化的非常奇怪的输出
【发布时间】:2013-05-23 12:58:32
【问题描述】:

在我的一个项目中,我用 const char 初始化了一个 const std::string&(在编译时就知道),打印的结果令人惊讶。

我在 Ubuntu 12.04x32 上使用 gcc 版本 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

示例:

#include <string>
#include <iostream>
using namespace std;

class A
{
    public:
        A() : str("test"){};
    const string& str;
};

int main(int argc,char* argv[])
{ 
  A a;
  cout<<a.str<<endl;
  return 0;
};

所以,正常情况下,它会显示“测试”,但是,这是我输出的一部分:

testP�����utf8)����lower_case_table_names�xW�xW� ��     ����127.0.0.1utf8W�Y127.0.0.1 via TCP/IP127.0.0.1
        �5.5.31-0ubuntu0.12.04.1rootW�rootW�1����metadata_use_info_schema!P�XP�� VARaءpW�P4:����SHOW SESSION VARIABLES LIKE 'lower_case_table_names'`(���TCP/IP (3)@!K!K!�
.....
<charset name="gb2312">
  <family>Simplified Chinese</family>
  <description>GB2312 Simplified Chinese</description>
  <alias>chinese</alias>
  <alias>iso-ir-58</alias>
   <collation name="gb2312_chinese_ci"  id="24" order="Chinese">
    <flag>primary</flag>
   <flag>compiled</flag>
  </collation>
  <collation name="gb2312_bin"  id="86">
    <flag>binary</flag>
    <flag>compiled</flag>
  </collation>
</charset>

输出连续 1000 行。

所以我的问题很简单:为什么? (我尝试在“测试”的末尾添加一个 \0,但没有改变)

【问题讨论】:

    标签: c++ gcc


    【解决方案1】:

    这是因为您正在取消引用一个悬空引用,这会给您的程序带来未定义的行为。根据 C++11 标准的第 12.2/5 段:

    [...] 临时绑定到构造函数的 ctor-initializer (12.6.2) 中的引用成员,直到 构造函数退出。 [...]

    这意味着 str 在构造函数的初始化列表中绑定到的临时 std::string 对象将在您取消引用 str 时失效。

    你有两种方法可以解决这个问题。要么将您的数据成员 str 设为 const char*,要么将其设为 std::string(不是引用类型)。我个人会选择最后一个选项:

    class A
    {
    public:
        A() : str("test") { }
        std::string str;
    };
    

    另请注意,函数定义后不需要分号。

    【讨论】:

    • @AndyProwl 这就是我的想法,但不太确定,我更喜欢在那里提问。让我吃惊的是它不会崩溃。
    • @Krozark:那是因为这是未定义的行为。它可能会崩溃(对我有用)也可能不会(对你没有)。您不能对具有未定义行为的程序做出假设。
    【解决方案2】:

    初始化string &amp; 需要string,而您提供的是const char *。编译器生成一个临时的string,初始化string &amp;,然后销毁string,当您尝试使用该引用时留下未定义的行为。

    【讨论】:

      【解决方案3】:

      您将str 引用绑定到一个临时的std::string,该临时std::string 在构造函数退出时消失。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-02-28
        • 2023-01-15
        • 1970-01-01
        • 2012-07-02
        • 1970-01-01
        • 2014-08-26
        • 1970-01-01
        • 2011-02-22
        相关资源
        最近更新 更多