title: C++ move assignment to uninitialized object?
body: <p>As follow up to:
  <a href="https://stackoverflow.com/questions/50777836/double-free-of-child-object-after-using-the-copy-constructor">Double free of child object after using the copy constructor</a></p>
  
  <p>I followed the rule of 5 as suggested.
  But now it seems like the move assignment is happening on an uninitialized object (to object id 0)? I expected it to move from object 3 to object 2.</p>
  
  <p>I have created the following (minimum?) example which seems to trigger my issue:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdint.h&gt;
  
  class A
  {
  public:
      A()
      {
          myCtr = ++ctr;
          printf("class A default Constructor - object id: %u\n", myCtr);
      }
  
      A(const A &amp;a2) {
          myCtr = ++ctr;
          printf("class A copy constructor - object id: %u\n", myCtr);
  
      }
  
      A(A &amp;&amp;a2) {
          myCtr = a2.myCtr;
          a2.myCtr = 0;
  
          printf("class A move constructor - object id: %u\n", myCtr);
  
      }
  
      A &amp; operator=(const A &amp;a2) {
          myCtr = ++ctr;
  
          printf("class A copy assignment - from object id: %u - to object id: %u\n", a2.myCtr, myCtr);
  
          return *this;
      }
  
      A &amp; operator=(A &amp;&amp;a2) {
          printf("class A move assignment - from object id: %u - to object id: %u\n", a2.myCtr, myCtr);
  
          if (this != &amp;a2) {
              //myCtr = a2.myCtr;
              //a2.myCtr = 0;
          }
  
          return *this;
      }
  
      ~A()
      {
          printf("class A destructor - object id: %u\n", myCtr);
      }
  
  private:
      uint64_t myCtr;
      static uint64_t ctr;
  };
  
  class B
  {
  public:
      B() {
  
      }
  
      B(char * input, uint32_t len) {
          for (uint32_t i = 0; i &lt; len; i++)
          {
              /* do something */
          }
      }
  
      B(const B &amp;b2) {
          characters = A(b2.characters);
      }
  
      B(B &amp;&amp;b2) {
          characters = A(b2.characters);
      }
  
      B &amp; operator=(const B &amp;b2) {
          characters = A(b2.characters);
      }
  
      B &amp; operator=(B &amp;&amp;b2) {
          characters = A(b2.characters);
      }
  
      ~B() {
  
      }
  
  
  private:
      A characters;
  };
  
  uint64_t A::ctr = 0;
  
  int main(int argc, char *argv[]) {
      B b1 = B((char *)"b1", 2);
      B b2 = b1;
  
      return 0;
  }
  </code></pre>
  
  <p>This produces the following output:</p>
  
  <pre><code>class A default Constructor - object id: 1
  class A default Constructor - object id: 2
  class A copy constructor - object id: 3
  class A move assignment - from object id: 3 - to object id: 0
  class A destructor - object id: 3
  class A destructor - object id: 2
  class A destructor - object id: 1
  </code></pre>
  
  <p>This is the line that i did not expect:</p>
  
  <p><code>class A move assignment - from object id: 3 - to object id: 0</code></p>
  
  <p>Expectation:</p>
  
  <p><code>class A move assignment - from object id: 3 - to object id: 2</code></p>
  
  <p>I am using the following compiler: Microsoft (R) C/C++ Optimizing Compiler Version 19.14.26429.4</p>
  
  <p>In case you down vote. Please specify why. I will gladly try to improve my question.</p>
  
  <p>Edit:</p>
  
  <p><strong>It seems like only Visual C++ compiler targeting the x86 platform makes this issue occur. It works fine with g++ (x86 &amp; x64), clang (x86 &amp; x64) and msvc (x64). This makes it harder to figure out the origin of this issue for me.</strong></p>