此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中的需要在转移前清除。