title: Exception when move assignment operator is used on a r-value
body: <p>I get a very strange crash (in debug mode only) when using the move assignment operator with a r-value:</p>
  
  <p>Cleaning and recompiling the code in debug mode does not help. The crash occurs before VulkanBuffer::operator=() is called.</p>
  
  <pre><code>// ok
  //VulkanBuffer myBuffer(logicalDevice, bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE);
  //buffer_ = std::move(myBuffer);
  
  // ok
  //VulkanBuffer myBuffer = VulkanBuffer(logicalDevice, bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE);
  //buffer_ = std::move(myBuffer);
  
  // crash in debug mode, release mode works fine
  //buffer_ = std::move( VulkanBuffer(logicalDevice, bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE) );
  
  // crash in debug mode, release mode works fine
  buffer_ = VulkanBuffer(logicalDevice, bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE);
  </code></pre>
  
  <p>I get this exception:</p>
  
  <p>Exception thrown at 0x0000000059F95E35 (nvoglv64.dll) in Vulkan.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.</p>
  
  <p>This exception occurs in the VulkanBuffer non-default constructor</p>
  
  <p>Can anyone shed some light on this? It seems to me that the code should be equivalent.</p>
  
  <p>The actual code is as below:</p>
  
  <p>Declaration of VulkanBuffer</p>
  
  <pre><code>#pragma once
  
  #include "VulkanLogicalDevice.h"
  #include "Vertex.h"
  
  #define GLFW_INCLUDE_VULKAN
  #include &lt;GLFW/glfw3.h&gt;
  
  #include &lt;memory&gt;
  #include &lt;vector&gt;
  
  class VulkanCommandPool;
  
  class VulkanBuffer
  {
  public:
      VulkanBuffer();
      VulkanBuffer(const std::shared_ptr&lt;VulkanLogicalDevice&gt;&amp; logicalDevice, VkDeviceSize deviceSizeInbytes, VkBufferUsageFlags bufferUsageFlags, VkSharingMode sharingMode);
      ~VulkanBuffer();
      VulkanBuffer(const VulkanBuffer &amp;rhs) = delete;
      VulkanBuffer &amp; operator=(const VulkanBuffer &amp;rhs) = delete;
      VulkanBuffer(VulkanBuffer &amp;&amp;rhs) = delete;
      VulkanBuffer &amp; operator=(VulkanBuffer &amp;&amp;rhs);
  
      VkBuffer &amp; handle() { return buffer_; }
      const VkBuffer &amp; handle() const { return buffer_; }
      const VkBufferCreateInfo &amp; getBufferInfo() const { return createInfo_; }
      void copyDataFrom(const VulkanBuffer &amp; rhs, const VulkanCommandPool &amp;commandPool, VkDeviceSize dataSizeInBytes);
  
      friend void swap(VulkanBuffer &amp;lhs, VulkanBuffer &amp;rhs);
  
  private:
      std::shared_ptr&lt;VulkanLogicalDevice&gt; logicalDevice_;
      VkBufferCreateInfo createInfo_;
      VkBuffer buffer_;
  };
  </code></pre>
  
  <p>Definition of VulkanBuffer</p>
  
  <pre><code>#include "VulkanBuffer.h"
  
  #include "VulkanCommandPool.h"
  #include "Vertex.h"
  #include &lt;iostream&gt;
  
  void swap(VulkanBuffer &amp;lhs, VulkanBuffer &amp;rhs)
  {
      std::swap(lhs.logicalDevice_, rhs.logicalDevice_);
      std::swap(lhs.buffer_, rhs.buffer_);
      std::swap(lhs.createInfo_, rhs.createInfo_);
  }
  
  VulkanBuffer::VulkanBuffer()
      : buffer_(VK_NULL_HANDLE)
  {}
  
  /// \param logicalDevice        Vulkan device
  /// \param deviceSizeInbytes    number of bytes of the vertices to be stored in this vertex buffer
  /// \param bufferUsageFlags     what will the buffer be used for, eg VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
  /// \param sharingMode          is the buffer used by more than one queue family, eg: VK_SHARING_MODE_EXCLUSIVE, VK_SHARING_MODE_CONCURRENT
  VulkanBuffer::VulkanBuffer(const std::shared_ptr&lt;VulkanLogicalDevice&gt;&amp; logicalDevice, VkDeviceSize deviceSizeInbytes, VkBufferUsageFlags bufferUsageFlags, VkSharingMode sharingMode)
      : logicalDevice_(logicalDevice), buffer_(VK_NULL_HANDLE)
  {
      createInfo_.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
      createInfo_.size = deviceSizeInbytes;
      createInfo_.usage = bufferUsageFlags; // indicates this data is for a vertex buffer.
      createInfo_.sharingMode = sharingMode; // ownership by one queue family or multiple
  
      if (vkCreateBuffer(logicalDevice-&gt;handle(), &amp;createInfo_, nullptr, &amp;buffer_) != VK_SUCCESS) {
          throw std::runtime_error("failed to create buffer!");
      }
  }
  
  VulkanBuffer::~VulkanBuffer()
  {
      if (buffer_ != VK_NULL_HANDLE)
          vkDestroyBuffer(logicalDevice_-&gt;handle(), buffer_, nullptr);
  }
  
  VulkanBuffer &amp; VulkanBuffer::operator=(VulkanBuffer &amp;&amp;rhs)
  {
      swap(*this, rhs);
      return *this;
  }
  
  void VulkanBuffer::copyDataFrom(const VulkanBuffer &amp; rhs, const VulkanCommandPool &amp;commandPool, VkDeviceSize dataSizeInBytes)
  {
      if (buffer_ == VK_NULL_HANDLE || rhs.buffer_ == VK_NULL_HANDLE)
      {
          std::cout &lt;&lt; "Illegal VulkanBuffer::copyDataFrom(), one or more buffers not initialized.\n";
          return;
      }
  
      VkCommandBufferAllocateInfo allocInfo = {};
      allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
      allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
      allocInfo.commandPool = commandPool.handle();
      allocInfo.commandBufferCount = 1;
  
      VkCommandBuffer commandBuffer;
      vkAllocateCommandBuffers(logicalDevice_-&gt;handle(), &amp;allocInfo, &amp;commandBuffer);
  
      VkCommandBufferBeginInfo beginInfo = {};
      beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
      beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
  
      vkBeginCommandBuffer(commandBuffer, &amp;beginInfo);
  
      VkBufferCopy copyRegion = {};
      copyRegion.size = dataSizeInBytes;
      vkCmdCopyBuffer(commandBuffer, rhs.handle(), buffer_, 1, &amp;copyRegion);
  
      vkEndCommandBuffer(commandBuffer);
  
      VkSubmitInfo submitInfo = {};
      submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
      submitInfo.commandBufferCount = 1;
      submitInfo.pCommandBuffers = &amp;commandBuffer;
  
      vkQueueSubmit(logicalDevice_-&gt;getGraphicsQueue(), 1, &amp;submitInfo, VK_NULL_HANDLE);
      vkQueueWaitIdle(logicalDevice_-&gt;getGraphicsQueue());
  
      vkFreeCommandBuffers(logicalDevice_-&gt;handle(), commandPool.handle(), 1, &amp;commandBuffer);
  
  }
  </code></pre>
  
  <p>edit: added this as part of Jherico's suggestion:
  When the class crashes, the following is printed from the class functions:</p>
  
  <pre><code>handle: 0000000000000000 VulkanBuffer: default ctor()
  handle: 0000000000000000 VulkanBuffer: non default ctor() start
  handle: 000001B2A00C84E0 VulkanBuffer: non default ctor() end
  handle: 0000000000000000 VulkanBuffer: non default ctor() start
  </code></pre>
  
  <p>when it does not crash, the following is printed</p>
  
  <pre><code>handle: 0000000000000000 VulkanBuffer: default ctor()
  handle: 0000000000000000 VulkanBuffer: non default ctor() start
  handle: 000001989ADB56E0 VulkanBuffer: non default ctor() end
  handle: 0000000000000000 VulkanBuffer: non default ctor() start
  handle: 000001989ADB6310 VulkanBuffer: non default ctor() end
  handle: 0000000000000000 VulkanBuffer: operator=()
  handle lhs: 0000000000000000 handle rhs: 000001989ADB6310 VulkanBuffer: Swap() start
  handle lhs: 000001989ADB6310 handle rhs: 0000000000000000 VulkanBuffer: Swap() end
  handle: 000001989ADB6310 VulkanBuffer: copyDataFrom()
  handle: 0000000000000000 VulkanBuffer: dtor() // instruction re-ordered here?
  handle: 000001989ADB56E0 VulkanBuffer: dtor()
  </code></pre>