Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
此C+中是否存在内存泄漏+;移动构造函数? 在C++编程语言第四版中,第76页中有移动构造函数使用的例子。p>_C++_Memory Leaks_Move Constructor - Fatal编程技术网

此C+中是否存在内存泄漏+;移动构造函数? 在C++编程语言第四版中,第76页中有移动构造函数使用的例子。p>

此C+中是否存在内存泄漏+;移动构造函数? 在C++编程语言第四版中,第76页中有移动构造函数使用的例子。p>,c++,memory-leaks,move-constructor,C++,Memory Leaks,Move Constructor,该类的定义如下: 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[] el

该类的定义如下:

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; 
}; 
定义了移动构造函数:

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; 
} 
我认为会导致内存泄漏的示例执行:

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 
}; 
这样的移动操作似乎会导致内存泄漏,因为y已在中分配了1000个元素

Vector y(1000); 

在y=std::move(x)行进行简单指针重新赋值;将使y指向的最初1000个整数自行离开。我假设,移动构造函数在移动之前必须有额外的代码行来取消分配指针“elem”。

假设移动构造函数实现正确,则不会。您引用的行调用移动赋值,而不是构造函数,因为
z
已经存在

这个C++移动构造函数中是否存在内存泄漏?< /P> 没有

我认为会导致内存泄漏的示例执行:

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 
}; 
显示的执行调用移动赋值,而不是移动构造函数

我假设,在移动之前,move构造函数必须有额外的代码行来取消分配指针“elem”


它不需要这样做,因为新构造的对象的指针在用move参数中的指针值初始化之前不能指向任何分配的内存。

是的,同意,这是move赋值: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; 
}
在y=std::move(x)行进行简单指针重新赋值;将离开 这些最初的1000个整数由y自己指向左边

指向double的指针的地址被复制到新对象(y)上,而旧对象(x)的指针被设置为nullptr。(它发生在未显示的移动分配方法中)

我假设,move构造函数必须有额外的代码行 移动前取消分配指针“elem”


这里不需要解除分配。指针在赋值过程中被“移动”(在移动构造过程中也会被移动)。双指针的清除应由析构函数处理。在x的情况下,析构函数最终会向nullptr开火。nullptr上的delete[]是一个noop。看


但是,正如前面所指出的,在移动分配过程中,需要清除y中分配的双精度项。

您显示的是移动副本构造函数。移动分配是如何实现的,因为在您的示例中就是这样调用的。与此无关,我觉得奇怪的是,您移动
elem
成员,但似乎忽略了移动
sz
成员。如果它足够重要,可以在移动源中归零,那么它可能足够重要,可以保留在移动目标中。在该成员初始值设定项之后有一个悬空的
,因此可能您只是忽略了为该构造函数粘贴所有代码(无论出于何种原因)。@WhozCraig看起来是这样的,但OP使用了注释并破坏了格式。查看
elem{a.elem},//“从z{a.sz}抓取元素”
@NathanOliver。是的,我更正了原来错误的粘贴代码,请参阅上面的代码。是的,同意,这是移动赋值:y=std::move(x);,不是构造函数。在书中,他们没有展示,只是提到移动分配的定义类似。但是,在移动分配定义中,据我所知,我们需要释放元素,对吗?像这样的?Vector&Vector::operator=(Vector&a){delete[]elem;elem=a.elem;sz=a.sz;a.elem=nullptr;//现在a没有元素a.sz=0;}@AndreyChertov,或者用另一个
Vector
交换
elem
ptr和
sz
,利用它的数据,让它来处理你自己的数据。如果你对搬家作业的实施有疑问,用它更新你的问题——这本书不是我的。很好!在移动分配中,交换看起来比删除[]更优雅。好电话。这样,每个对象在超出范围时都会自行处理。在这种情况下,不应使用nullptr。“指针在赋值过程中只是‘移动’……双指针的清理应由析构函数处理。”如果我们在移动赋值中不清理,最初分配的1000个初始y将泄漏。析构函数将只删除最初在x中分配并移动到y的1000。但是在y中分配的需要在elem=a.elem之前删除[];啊,现在,。好电话。是的,Y中的需要在转移前清除。