dimanche 28 août 2016

std::move changes address of variables?

I found unexpected (at least for me) behavior.

class A
{
    char  _text[100];
    char* _beg;
    char* _end;
public:
    explicit A(char* text, size_t tsize) : _beg(&text[0]), _end(&text[std::min(tsize, 99)]) 
    {
        memcpy(_text, text, std::min(tsize, 99));
        _end = '\0';
    }
    inline std::string get_text()
    {
        return std::move(std::string(_beg, _end));  
    }
};

After that somewhere in code I do that:

  A* add_A(A&& a)
  {
     list_a.push_back(std::move(a));
     return &(list_a.back());
  }

  std::list<A> list_a;
  {
      add_A(A("my_text", 7));
      list_a.back().get_text(); //returns "my_text"
  }
  list_a.back().get_text(); //returns trash

As only I move this class (using std::move), and call get_text() of object that was moved, I get trash, as if after movement address of variable _text changed, and so _beg and _end points to nowhere.

Does address of variables really can be changes after std::move (I thought move don't really move object, it was invented for that)?

If it can be changed, what is usual pattern to handle it (to change pointers accordingly)?

If it can't be change, may that behavior happens because I try to move such object to std::list (and so there somehow happens copying, it changes address of variables and makes pointers point to wrong positions)?

Aucun commentaire:

Enregistrer un commentaire