为什么离开作用域后,指向字符串字面值的外部指针会丢失?(C++)

3
在下面的程序中:
#include <string>
#include <deque>
#include <assert.h>

struct Foo {
    // member var
    const std::string *m_pstr;

    // ctor
    Foo (const std::string *pS) : m_pstr (pS) {}

    // copy ctor
    Foo (const Foo& other) : m_pstr (other.m_pstr) {}

    // swap
    void swap (Foo &other) { std::swap (m_pstr, other.m_pstr); }

    // assignment operator
    Foo& operator=(Foo tmp)
    {
        this->swap (tmp);
        return *this;
    }

    // dtor
    ~Foo () {}
};


struct FooQueue {
    // member var
    std::deque<Foo> m_q;

    void Enqueue (const Foo &f)
    {
        m_q.push_back (f);
        assert (*(m_q.front().m_pstr) == std::string("Hello")); // This Passes
    }

    void Enqueue (const std::string &s)
    {
        Foo f (&s);
        Enqueue (f);
        assert (*(m_q.front().m_pstr) == std::string("Hello")); // This Passes
    }
};


void ProcessEvent (FooQueue &fq)
{
    fq.Enqueue ("Hello");
    assert (*(fq.m_q.front().m_pstr) == std::string("Hello"));  // This Fails
}


int main (int argc, char* argv[])
{
    FooQueue fq;
    ProcessEvent (fq);
    return 0;
}

函数ProcessEvent()中的断言失败了,我不知道为什么。我希望作为参数传递给fq.Enqueue()的字符串文字“Hello”可以通过作用域的变化而持久存在(因为这个),并且我希望成员指针m_pstr也可以在作用域的变化中继续指向该字符串文字。有人能给我解释一下吗?


1
类型为 const char[6] 的字符串字面量可以存活,但隐式转换的右值 std::string 无法存活。 - PeterT
2个回答

5
在这种情况下,一个临时的字符串对象将被构造来存储 "Hello"。然后将这个临时对象绑定到字符串对象 s 上。
void Enqueue (const std::string &s)

这意味着临时变量的生命周期被延长到了字符串s的范围内。然而,当该函数退出时,s将被销毁。

因此,在ProcessEvent中,该字符串已经不存在了。


您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - sifferman

1
您正在将从字面值“Hello”转换而来的临时std::string排队。 在调用fq.Enqueue()后,该临时对象将被销毁,您的队列将引用已删除的对象。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接