Search code examples
c++streammanipulators

pword() value modified by another stream


The os.pword(index) method is supposed to return current date format specified by a custom manipulator. The result of pword() gets, however, modified by a different stream by it's str(string) method.

ostringstream os;
istringstream is;
CDate f ( 2000, 5, 12 );

os << date_format ( "%Y-%m-%d" ) << f;
is.clear ();
is.str ( "05.06.2003" ); // causes pword() to return "05.06.2003" instead of "%Y-%m-%d"
os.str ("");
os << f;

Class methods:

struct date_format
{
    static const int index;
    string format;

    explicit date_format(const char * fmt)
    {
        format = string(fmt);
    }

    friend ostream & operator<<(ostream & s, const date_format & df)
    {
        s.pword(index) = (void*)df.format.c_str();
        return s;
    }

};

const int date_format::index = ios_base::xalloc();

class CDate
{
    ...
    friend ostream & operator<<(ostream & os, const CDate & cdate)
    {
        /* should point to the current date format of os */ 
        const char * ptr = (const char*)os.pword(date_format::index);
        ...
        return os;
    }
}

What causes such behaviour and what can be done to avoid it?


Solution

  • You're experiencing undefined behvaior. In your operator<<(ostream & s, const date_format& df) you set s.pword(index) to a pointer to a data member of a temporary date_format instance. Since date_format( "%Y-%m-%d" ) destructs at the end of the expression, your stream is left with a dangling pointer.

    Try making a deep copy of the string before you set a pointer to it.