After studying an example for Move Semantics of C++11, I write a more complete code snippet:

#include 
using namespace std;
class Intvec {
  public:
    explicit Intvec(size_t num = 0)
      : m_size(num), m_data(new int[m_size]) {
      log("constructor");
    }
    ~Intvec() {
      log("destructor");
      if (m_data) {
        delete[] m_data;
        m_data = 0;
      }
    }
    Intvec(const Intvec& other) : m_size(other.m_size), m_data(new int[m_size]) {
      log("copy constructor");
      for (size_t i = 0; i < m_size; ++i)
        m_data[i] = other.m_data[i];
    }
    Intvec(Intvec&& other) {
      log("move constructor");
      std::swap(m_size, other.m_size);
      std::swap(m_data, other.m_data);
      other.m_size = 0;
      other.m_data = nullptr;
    }
    Intvec& operator=(const Intvec& other) {
      log("copy assignment operator");
      Intvec tmp(other);
      std::swap(m_size, tmp.m_size);
      std::swap(m_data, tmp.m_data);
      return *this;
    }
    Intvec& operator=(Intvec&& other) {
      log("move assignment operator");
      std::swap(m_size, other.m_size);
      std::swap(m_data, other.m_data);
      return *this;
    }
  private:
    void log(const char* msg) {
      cout << "[" << this << "] " << msg << "\n";
    }
    size_t m_size;
    int* m_data;
};
int main(void) {
  Intvec v1(20);
  Intvec v2;
  cout << "assigning lvalue...\n";
  v2 = v1;
  cout << "ended assigning lvalue...\n";
  //Intvec v4 = std::move(Intvec(30));
  Intvec v3;
  cout << "move assigning...\n";
  v3 = Intvec(30);
  cout << "ended move assigning...\n";
  cout << "move constructor\n";
  Intvec v4 = std::move(v3);
  cout << "ended move constructor\n";
  return 0;
}

Pay attention to last two lines in 'move constructor':

...
      other.m_size = 0;
      other.m_data = nullptr;
...

Since 'move constructor' will not set initial value for m_size and m_data of 'v4', the m_size and m_data of 'v3' will be uninitial after swaps. Adding the two lines of code means to initialize m_size and m_data of 'v3'.