【发布时间】:2016-07-21 16:24:24
【问题描述】:
在 Stroustrups The C++ Programming Language Fourth Edition,第 76 页,有使用移动构造函数的示例。
类是这样定义的:
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'。
【问题讨论】:
-
您展示的是移动复制构造函数。移动分配是如何实现的,因为这就是您的示例中调用的内容。
-
无关,我觉得你移动
elem成员很奇怪,但似乎忽略了移动sz成员。如果将移动源归零足够重要,那么保留移动目标可能足够重要。在该成员初始化程序之后有一个悬空的,,所以也许您只是忽略了为该构造函数粘贴 all 代码(无论出于何种原因)。 -
@WhozCraig 看起来确实如此,但 OP 使用了评论并破坏了格式。看看
elem{a.elem}, // "grab the elements" from a z{a.sz}。 -
@NathanOliver 优秀。
-
是的,我更正了最初错误粘贴的代码,请参见上面的代码。
标签: c++ memory-leaks move-constructor