Is there a memory leak in this C ++ move constructor?

In Stroustrups The fourth release of the C ++ programming language on page 76 shows an example of using the move constructor.

The class is defined as follows:

class Vector { 
private: 
  double∗ elem; // elem points to an array of sz doubles 
  int sz; 
public: 
  Vector(int s) :elem{new double[s]}, sz{s} 
  { for (int i=0; i!=s; ++i) elem[i]=0; // initialize elements } 

  ~Vector() { delete[] elem; } // destructor: release resources 
  Vector(const Vector& a); // copy constructor 
  Vector& operator=(const Vector& a); // copy assignment 
  Vector(Vector&& a); // move constructor 
  Vector& operator=(Vector&& a); // move assignment 

  double& operator[](int i); 
  const double& operator[](int i) const; 
  int size() const; 
}; 

The move constructor is defined:

Vector::Vector(Vector&& a) :elem{a.elem}, // "grab the elements" from a 
  sz{a.sz} 
{ 
  a.elem = nullptr; // now a has no elements 
  a.sz = 0; 
} 

An example run that I think will cause a memory leak:

Vector f() 
{ 
  Vector x(1000); 
  Vector y(1000); 
  Vector z(1000); 
  // ... 
  z=x; //we get a copy 
  y = std::move(x); // we get a move 
  // ... 
  return z; //we get a move 
}; 

It seems that such a move operation will cause a memory leak, because 1000 items were allocated in y

Vector y(1000); 

and a simple reassignment of the pointer in the string y = std :: move (x); will leave these initial 1000 ints that y points to are left on their own. I suggest that the move constructor should have an extra line of code to de-select the 'elem' pointer before the move.

+4
4

, , . , , , , z .

+2

++?

.

, , , :

, .

, 'elem' .

, , move.

+2

, , : y = std:: move (x);, . , , . , , , ? - .

Vector& Vector::operator=(Vector&& a)
{ 
  delete[] elem;
  elem = a.elem;
  sz = a.sz;
  a.elem = nullptr; // now a has no elements 
  a.sz = 0; 
}
0

y = std:: move (x); 1000 ints, y, .

double (y), (x) nullptr. ( )

, 'elem'.

No exemption is required here. The pointer simply “moves” during the assignment (it also moves during the move). Clearing the double pointer must be handled by the destructor. In the case of x, the destructor ultimately runs on nullptr. delete [] on nullptr is noop. see http://www.cplusplus.com/reference/new/operator%20delete[†/

However, the doubling highlighted in y must be cleared during the move assignment, as indicated.

0
source

Source: https://habr.com/ru/post/1648679/


All Articles