C++ - 重载赋值运算符内存泄漏

Ven*_*nom 2 c++ memory-leaks operator-overloading copy-constructor assignment-operator

我有一个类方法,它与一个对象的副本一起工作(确切地说是*).泄漏发生在重载的赋值运算符中 - 无论如何,这就是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;
}
Run Code Online (Sandbox Code Playgroud)

复制构造函数:

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];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

作业运营商:

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;
}
Run Code Online (Sandbox Code Playgroud)

析构函数:

Grid::~Grid()
{
    int dimensions = static_cast<int>(_size);
    for (int i = 0; i < dimensions; ++i)
    {
        delete[] _squares[i];
    }
    delete[] _squares;
}
Run Code Online (Sandbox Code Playgroud)

Pup*_*ppy 5

您的代码存在的问题是您手动管理所有资源.这是非常不安全的,并且正确地做了大量的头痛,正如现有的答案都是错误的恰当证明的那样.

使用std::vector.该课程将自动为您管理所有内存,让您不必自己动手.这将大大简化您的代码,并使其正确.

此外,自我分配检查是一种古老的反模式.不要包括自我分配的检查.如果您的赋值运算符(std::vector在大多数情况下您不需要编写自己的基于内存的内存管理)在没有特殊情况下无法处理自我赋值,那么它就会被破坏.