Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. std::swap Corruption [Answered]

std::swap Corruption [Answered]

Scheduled Pinned Locked Moved C / C++ / MFC
questionhelpcsharpvisual-studiodebugging
2 Posts 1 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Skippums
    wrote on last edited by
    #1

    I am using Visual Studio 2010 Pro, and have a unique issue that I'm hoping someone can help with. I overloaded the move operator = on a class, with the following code:

    template<class T>
    MyClass<T> &MyClass<T>::operator =(MyClass &&other) {
    if (this != &other) {
    std::swap(m_Data , other.m_Data ); // T*
    std::swap(m_Size1, other.m_Size1); // size_t
    std::swap(m_Size2, other.m_Size2); // size_t
    std::swap(m_Size3, other.m_Size3); // size_t
    std::swap(m_Bool1, other.m_Bool1); // bool
    std::swap(m_Bool2, other.m_Bool2); // bool
    }
    return *this;
    }

    When I enter this method in the debugger, all of the fields of both *this and other are what I expect. In case it matters, the values are:

         \*this     other
    

    m_Data 0 0x15E4D2EC0
    m_Size1 0 5041
    m_Size2 0 5041
    m_Size3 0 1
    m_Bool1 true false
    m_Bool2 true true

    My expectation is that the calls to std::swap exchange the values of all the aforementioned fields. However, on the first call to swap, when I step into the function, I get that _Left = 0 and _Right = 0x7FEF5B07EDF. WTF? Why did the value of _Right change from 0x15E4D2EC0? Even more confusing, is that at the end of the function, _Left = 0x7FEF5B07EDF, _Right = 0, but upon returning, the value of other.m_Data has NOT changed to 0. Additionally, the following fields in the "other" object changed to the values indicated (after only executing the first std::swap):

             other
    

    m_Data 0x7FEF5B07EDF (should be 0)
    m_Size1 67251472 (should be 5041)
    m_Size2 0 (should be 5041)
    m_Size3 67257296 (should be 1)
    m_Bool1 true (should be false)
    m_Bool2 true (should be true)

    WTF? Why does calling std::swap on a single field totally hose my entire object? It is as if the first call somehow changed the type of other. Can anyone shed some light onto what is happening here? Additionally, when the future calls of std::swap are executed (all but the first), they copy the value from other to *this, but don't change the value of other (for example, after executing std::swap(m_Size1, other.m_Size1), I would expect m_Size1 = 67251472 (which it does), and other.m_Size1 = 0 (it is still equal to 67251472). Thanks,

    Sounds like somebody's got a case of the Mondays -Jeff

    S 1 Reply Last reply
    0
    • S Skippums

      I am using Visual Studio 2010 Pro, and have a unique issue that I'm hoping someone can help with. I overloaded the move operator = on a class, with the following code:

      template<class T>
      MyClass<T> &MyClass<T>::operator =(MyClass &&other) {
      if (this != &other) {
      std::swap(m_Data , other.m_Data ); // T*
      std::swap(m_Size1, other.m_Size1); // size_t
      std::swap(m_Size2, other.m_Size2); // size_t
      std::swap(m_Size3, other.m_Size3); // size_t
      std::swap(m_Bool1, other.m_Bool1); // bool
      std::swap(m_Bool2, other.m_Bool2); // bool
      }
      return *this;
      }

      When I enter this method in the debugger, all of the fields of both *this and other are what I expect. In case it matters, the values are:

           \*this     other
      

      m_Data 0 0x15E4D2EC0
      m_Size1 0 5041
      m_Size2 0 5041
      m_Size3 0 1
      m_Bool1 true false
      m_Bool2 true true

      My expectation is that the calls to std::swap exchange the values of all the aforementioned fields. However, on the first call to swap, when I step into the function, I get that _Left = 0 and _Right = 0x7FEF5B07EDF. WTF? Why did the value of _Right change from 0x15E4D2EC0? Even more confusing, is that at the end of the function, _Left = 0x7FEF5B07EDF, _Right = 0, but upon returning, the value of other.m_Data has NOT changed to 0. Additionally, the following fields in the "other" object changed to the values indicated (after only executing the first std::swap):

               other
      

      m_Data 0x7FEF5B07EDF (should be 0)
      m_Size1 67251472 (should be 5041)
      m_Size2 0 (should be 5041)
      m_Size3 67257296 (should be 1)
      m_Bool1 true (should be false)
      m_Bool2 true (should be true)

      WTF? Why does calling std::swap on a single field totally hose my entire object? It is as if the first call somehow changed the type of other. Can anyone shed some light onto what is happening here? Additionally, when the future calls of std::swap are executed (all but the first), they copy the value from other to *this, but don't change the value of other (for example, after executing std::swap(m_Size1, other.m_Size1), I would expect m_Size1 = 67251472 (which it does), and other.m_Size1 = 0 (it is still equal to 67251472). Thanks,

      Sounds like somebody's got a case of the Mondays -Jeff

      S Offline
      S Offline
      Skippums
      wrote on last edited by
      #2

      Nevermind: I'm an idiot. I didn't realize that rvalue references are returned automatically, and had a function declared similar to the following:

      MyClass<double> &&Foo() {
      MyClass<double> result();
      return std::move(result);
      }

      I simply had to remove the double ampersand from the return type, and my move constructor/assignment operator were correctly called. The reason that I saw this weird behavior was because the object that I had a reference to was allocated on the stack. Once enough functions were called (overwriting any pre-existing, invalid stuff on the stack), the object I was using was overwritten. Thanks for anyone who looked into this!

      Sounds like somebody's got a case of the Mondays -Jeff

      1 Reply Last reply
      0
      Reply
      • Reply as topic
      Log in to reply
      • Oldest to Newest
      • Newest to Oldest
      • Most Votes


      • Login

      • Don't have an account? Register

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • World
      • Users
      • Groups