3

In the following program:

#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;
}

the assertion within function ProcessEvent() fails, and I don't know why. I would expect the string literal "Hello" in the argument to fq.Enqueue() to persist through changes in scope (because of this), and I would expect the member pointer m_pstr also to continue to point to that string literal through changes in scope. Can someone enlighten me?

sifferman
  • 2,955
  • 2
  • 27
  • 37
  • 1
    The string literal of type `const char[6]` survives, but the implictly converted rvalue `std::string` does not survive – PeterT Nov 19 '14 at 03:47

2 Answers2

5

In this case a temporary string object would be constructed to store "Hello". And then this temporary is bound to string object s.

void Enqueue (const std::string &s)

That means life time of temporary is extended to the scope of string s.However when this function exits, s will be destroyed.

So, in ProcessEvent that string has long gone.

ravi
  • 10,994
  • 1
  • 18
  • 36
  • Yes! of course. So my incorrect assumption was that the lifetime of std::string("Hello") was the same as the static "Hello". Thank you, all who provided correct answers. – sifferman Nov 19 '14 at 16:42
1

You are enqueing a temporary std::string converted from the litteral "Hello". The temporary will be destroyed after the call to fq.Enqueue(), and your queue will reference a deleted object.

kuroi neko
  • 8,479
  • 1
  • 19
  • 43