【发布时间】:2014-10-16 19:44:42
【问题描述】:
我有一个类方法可以处理对象的副本(准确地说是 *this)。泄漏发生在重载的赋值运算符中 - 无论如何,这就是 Visual Leak Detector 所说的。我正在做的是使用副本,如果完成的工作令人满意,我会将新创建的对象复制回来。我还实现了自定义析构函数、复制构造函数和赋值运算符,因为很明显,动态分配的内存会出现问题。我的 C++ 经验非常有限,因此代码中可能存在一些邪恶的东西。
如果需要,我会提供更多信息。
有问题的方法:
bool Grid::SurroundShipSquares(int top, int bottom, int left, int right)
{
// copying itself
Grid gridCopy(*this);
Square** squaresCopy = gridCopy.GetSquares();
for (int i = top; i <= bottom; ++i)
{
for (int j = left; j <= right; ++j)
{
if (squaresCopy[i][j].GetState() != SquareState::Vacant)
return false;
(squaresCopy[i][j]).SetState(SquareState::Unoccupiable);
}
}
// the problem occurs here
*this = gridCopy;
return true;
}
复制构造函数:
Grid::Grid(const Grid& source)
{
_position = source._position;
_size = source._size;
int dimensions = static_cast<int>(_size);
_squares = new Square*[dimensions];
for (int i = 0; i < dimensions; ++i)
{
_squares[i] = new Square[dimensions];
for (int j = 0; j < dimensions; ++j)
{
_squares[i][j] = source._squares[i][j];
}
}
}
赋值运算符:
Grid& Grid::operator=(const Grid& source)
{
if (this == &source)
return *this;
_position = source._position;
_size = source._size;
int dimensions = static_cast<int>(_size);
_squares = new Square*[dimensions];
for (int i = 0; i < dimensions; ++i)
{
_squares[i] = new Square[dimensions];
for (int j = 0; j < dimensions; ++j)
{
_squares[i][j] = source._squares[i][j];
}
}
return *this;
}
析构函数:
Grid::~Grid()
{
int dimensions = static_cast<int>(_size);
for (int i = 0; i < dimensions; ++i)
{
delete[] _squares[i];
}
delete[] _squares;
}
【问题讨论】:
-
省去所有麻烦,改用copy-and-swap idiom。
-
不幸的是,这个问题再次证明了为什么我最近在 SE 网络的这一部分的参与度下降了。
-
@DavidHammen 很抱歉出现这种情况,但我肯定不是罪魁祸首。我所做的只是发布一个诚实的新手问题。
-
@Venom:你肯定不是罪魁祸首。一方面,您应该认真考虑使用标准库中的工具。另一方面,您最终需要学会编写安全代码并正确管理资源。在这个网站上有一群连续投票者不会让其他人回答你问题的后半部分。做丹尼尔弗雷在他的评论中所说的。学习复制和交换习语。你应该考虑使用 std::vector 如果它适合你的需要。
-
@DavidHammen 您完全可以按照自己的方式回答问题。其他人认为它有害,他们(在评论部分)向您解释了原因。这是他们的选择。停止整个抱怨受害。
标签: c++ memory-leaks operator-overloading copy-constructor assignment-operator