C ++ Valgrind错误包括"无效写入大小为8"但没有内存泄漏

时间:2015-01-13 12:33:31

标签: c++ memory memory-management memory-leaks valgrind

我制作了一个简单的C ++国际象棋程序,并且一直在体验来自valgrind的上述消息(最后添加):

我为每一件都有课程,他们都从一个抽象类ChessPiece继承。抽象类在其中包含一个字符串和一个枚举。我还有一个“Cell”类,它知道如何绘制自己,并且持有一个指向ChessPiece的指针,该指针保存当前在哪个部分(如果它是空的则指针是nullptr)

Board类是具有移动,检查合法性等所有逻辑的类。它具有Cell类的向量向量(表示单元矩阵)。

基本上除了ChessPieces之外的所有内容都会自动分配到内存中,并且使用“new”分配这些部分,以便它们是堆的一部分

我已在相关代码(和valgrind报告)中包含。

ChessPiece Class:

ChessPiece::ChessPiece(string asciiCode, Player player, PieceType piece)
    : _asciiCode(asciiCode), _player(player), _piece(piece)
{

}

ChessPiece::ChessPiece()
    :_asciiCode("")
{

}

and also holds several other getter functions

Cell Class:

ChessPiece * _pieceOccupying = nullptr;

Cell::Cell()
    :Cell(0, 0)
{
    setColour();
}

Cell::~Cell()
{
    delete _pieceOccupying;
}

Cell::Cell(int row, int col)
    : _row(row), _col(col), _occupied(false)
{
    setColour(); //sets enum according to row and col
}

Cell::Cell(int row, int col, ChessPiece * occupying)
    : _row(row), _col(col), _pieceOccupying(occupying), _occupied(true)
{
    setColour(); //sets enum according to row and col
}

void Cell::setOccupying(ChessPiece * occupying)
{
    if (occupying == nullptr)
    {
        _occupied = false;
    }
    else 
    {
        _pieceOccupying = occupying;
        _occupied = true;
    }  
}

ChessPiece * Cell::getOccupyingPiece()
{
    if (_occupied) 
    {
        return _pieceOccupying;
    }
    return nullptr;

}

void Cell::setEmptyCell()
{
    _occupied = false;
    _pieceOccupying = nullptr;
}

董事会成员:

private vector< vector<Cell> > _board;

Board::Board()
{
    for (int i = 0; i < BOARD_SIZE; i++)
    {
        vector<Cell> row; //create empty row
        for (int j = 0; j < BOARD_SIZE; j++)
        {
            row.push_back((Cell(i, j)));
        }
        _board.push_back(row);
    }

    initPieces();
}

void Board::initPieces()
{
    //Set Pawns
    for (int i = 0; i < BOARD_SIZE; i++)
    {
        _board[1][i].setOccupying(new Pawn(White));
        _board[6][i].setOccupying(new Pawn(Black));
    }

    //Set Rooks
    _board[0][0].setOccupying(new Rook(White));
    _board[0][7].setOccupying(new Rook(White));
    _board[7][7].setOccupying(new Rook(Black));
    _board[7][0].setOccupying(new Rook(Black));

    //Set Knights
    _board[0][1].setOccupying(new Knight(White));
    _board[0][6].setOccupying(new Knight(White));
    _board[7][6].setOccupying(new Knight(Black));
    _board[7][1].setOccupying(new Knight(Black));

    //Set Bishops
    _board[0][2].setOccupying(new Bishop(White));
    _board[0][5].setOccupying(new Bishop(White));
    _board[7][5].setOccupying(new Bishop(Black));
    _board[7][2].setOccupying(new Bishop(Black));

    //Set Queens
    _board[0][3].setOccupying(new Queen(White));
    _board[7][3].setOccupying(new Queen(Black));

    //Set Kings
    _board[0][4].setOccupying(new King(White));
    _board[7][4].setOccupying(new King(Black));
    _whiteKingCell = &_board[0][4];
    _blackKingCell = &_board[7][4];

}

我已经推断出Board类中的以下函数是有问题的,特别是问题似乎是吃另一块(如果我运行一个小型的国际象棋游戏而不吃另一块并退出,valgrind显示没有错误全部):

void Board::actualMove(Cell * srcCell, Cell * destCell, Player playerMoving)
{

    //do actual move
    ChessPiece * destPiece = nullptr;
    bool previousMoved = false;
    destPiece = destCell->getOccupyingPiece();
    destCell->setOccupying(srcCell->getOccupyingPiece());
    destCell->getOccupyingPiece()->setMoved(true);
    srcCell->setEmptyCell();
    delete destPiece;
    destPiece = nullptr;
}

Valgrind说没有任何内存泄漏,但它表示存在无效的读写操作。我似乎无法理解我在这里做错了什么。程序运行正常,没有任何错误。 我应该为ChessPiece创建自己的析构函数吗?

我应该在Cell的析构函数中做更多的事情吗?

以下是详细的Valgrind报告。 感谢任何帮助的人

Valgrind报告:

==3526== Invalid write of size 8
==3526==    at 0x403554: ChessPiece::~ChessPiece() (ChessPiece.h:13)
==3526==    by 0x404F43: Cell::~Cell() (Cell.cpp:14)
==3526==    by 0x401CBC: void std::_Destroy<Cell>(Cell*) (stl_construct.h:93)
==3526==    by 0x401C85: void std::_Destroy_aux<false>::__destroy<Cell*>(Cell*, Cell*) (stl_construct.h:103)
==3526==    by 0x401C30: void std::_Destroy<Cell*>(Cell*, Cell*) (stl_construct.h:126)
==3526==    by 0x401BBC: void std::_Destroy<Cell*, Cell>(Cell*, Cell*, std::allocator<Cell>&) (stl_construct.h:151)
==3526==    by 0x401AFE: std::vector<Cell, std::allocator<Cell> >::~vector() (stl_vector.h:415)
==3526==    by 0x401AC6: void std::_Destroy<std::vector<Cell, std::allocator<Cell> > >(std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:93)
==3526==    by 0x401A8F: void std::_Destroy_aux<false>::__destroy<std::vector<Cell, std::allocator<Cell> >*>(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:103)
==3526==    by 0x401A3A: void std::_Destroy<std::vector<Cell, std::allocator<Cell> >*>(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:126)
==3526==    by 0x4019C6: void std::_Destroy<std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> > >(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*, std::allocator<std::vector<Cell, std::allocator<Cell> > >&) (stl_construct.h:151)
==3526==    by 0x401908: std::vector<std::vector<Cell, std::allocator<Cell> >, std::allocator<std::vector<Cell, std::allocator<Cell> > > >::~vector() (stl_vector.h:415)
==3526==  Address 0x5a1fda0 is 0 bytes inside a block of size 32 free'd
==3526==    at 0x4C2C2BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3526==    by 0x404F4B: Cell::~Cell() (Cell.cpp:14)
==3526==    by 0x401CBC: void std::_Destroy<Cell>(Cell*) (stl_construct.h:93)
==3526==    by 0x401C85: void std::_Destroy_aux<false>::__destroy<Cell*>(Cell*, Cell*) (stl_construct.h:103)
==3526==    by 0x401C30: void std::_Destroy<Cell*>(Cell*, Cell*) (stl_construct.h:126)
==3526==    by 0x401BBC: void std::_Destroy<Cell*, Cell>(Cell*, Cell*, std::allocator<Cell>&) (stl_construct.h:151)
==3526==    by 0x401AFE: std::vector<Cell, std::allocator<Cell> >::~vector() (stl_vector.h:415)
==3526==    by 0x401AC6: void std::_Destroy<std::vector<Cell, std::allocator<Cell> > >(std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:93)
==3526==    by 0x401A8F: void std::_Destroy_aux<false>::__destroy<std::vector<Cell, std::allocator<Cell> >*>(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:103)
==3526==    by 0x401A3A: void std::_Destroy<std::vector<Cell, std::allocator<Cell> >*>(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:126)
==3526==    by 0x4019C6: void std::_Destroy<std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> > >(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*, std::allocator<std::vector<Cell, std::allocator<Cell> > >&) (stl_construct.h:151)
==3526==    by 0x401908: std::vector<std::vector<Cell, std::allocator<Cell> >, std::allocator<std::vector<Cell, std::allocator<Cell> > > >::~vector() (stl_vector.h:415)
==3526== 
==3526== Invalid read of size 8
==3526==    at 0x4EF14C0: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==3526==    by 0x40356A: ChessPiece::~ChessPiece() (ChessPiece.h:13)
==3526==    by 0x404F43: Cell::~Cell() (Cell.cpp:14)
==3526==    by 0x401CBC: void std::_Destroy<Cell>(Cell*) (stl_construct.h:93)
==3526==    by 0x401C85: void std::_Destroy_aux<false>::__destroy<Cell*>(Cell*, Cell*) (stl_construct.h:103)
==3526==    by 0x401C30: void std::_Destroy<Cell*>(Cell*, Cell*) (stl_construct.h:126)
==3526==    by 0x401BBC: void std::_Destroy<Cell*, Cell>(Cell*, Cell*, std::allocator<Cell>&) (stl_construct.h:151)
==3526==    by 0x401AFE: std::vector<Cell, std::allocator<Cell> >::~vector() (stl_vector.h:415)
==3526==    by 0x401AC6: void std::_Destroy<std::vector<Cell, std::allocator<Cell> > >(std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:93)
==3526==    by 0x401A8F: void std::_Destroy_aux<false>::__destroy<std::vector<Cell, std::allocator<Cell> >*>(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:103)
==3526==    by 0x401A3A: void std::_Destroy<std::vector<Cell, std::allocator<Cell> >*>(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:126)
==3526==    by 0x4019C6: void std::_Destroy<std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> > >(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*, std::allocator<std::vector<Cell, std::allocator<Cell> > >&) (stl_construct.h:151)
==3526==  Address 0x5a1fda8 is 8 bytes inside a block of size 32 free'd
==3526==    at 0x4C2C2BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3526==    by 0x404F4B: Cell::~Cell() (Cell.cpp:14)
==3526==    by 0x401CBC: void std::_Destroy<Cell>(Cell*) (stl_construct.h:93)
==3526==    by 0x401C85: void std::_Destroy_aux<false>::__destroy<Cell*>(Cell*, Cell*) (stl_construct.h:103)
==3526==    by 0x401C30: void std::_Destroy<Cell*>(Cell*, Cell*) (stl_construct.h:126)
==3526==    by 0x401BBC: void std::_Destroy<Cell*, Cell>(Cell*, Cell*, std::allocator<Cell>&) (stl_construct.h:151)
==3526==    by 0x401AFE: std::vector<Cell, std::allocator<Cell> >::~vector() (stl_vector.h:415)
==3526==    by 0x401AC6: void std::_Destroy<std::vector<Cell, std::allocator<Cell> > >(std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:93)
==3526==    by 0x401A8F: void std::_Destroy_aux<false>::__destroy<std::vector<Cell, std::allocator<Cell> >*>(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:103)
==3526==    by 0x401A3A: void std::_Destroy<std::vector<Cell, std::allocator<Cell> >*>(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:126)
==3526==    by 0x4019C6: void std::_Destroy<std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> > >(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*, std::allocator<std::vector<Cell, std::allocator<Cell> > >&) (stl_construct.h:151)
==3526==    by 0x401908: std::vector<std::vector<Cell, std::allocator<Cell> >, std::allocator<std::vector<Cell, std::allocator<Cell> > > >::~vector() (stl_vector.h:415)
==3526== 
==3526== Invalid free() / delete / delete[] / realloc()
==3526==    at 0x4C2C2BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3526==    by 0x404F4B: Cell::~Cell() (Cell.cpp:14)
==3526==    by 0x401CBC: void std::_Destroy<Cell>(Cell*) (stl_construct.h:93)
==3526==    by 0x401C85: void std::_Destroy_aux<false>::__destroy<Cell*>(Cell*, Cell*) (stl_construct.h:103)
==3526==    by 0x401C30: void std::_Destroy<Cell*>(Cell*, Cell*) (stl_construct.h:126)
==3526==    by 0x401BBC: void std::_Destroy<Cell*, Cell>(Cell*, Cell*, std::allocator<Cell>&) (stl_construct.h:151)
==3526==    by 0x401AFE: std::vector<Cell, std::allocator<Cell> >::~vector() (stl_vector.h:415)
==3526==    by 0x401AC6: void std::_Destroy<std::vector<Cell, std::allocator<Cell> > >(std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:93)
==3526==    by 0x401A8F: void std::_Destroy_aux<false>::__destroy<std::vector<Cell, std::allocator<Cell> >*>(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:103)
==3526==    by 0x401A3A: void std::_Destroy<std::vector<Cell, std::allocator<Cell> >*>(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:126)
==3526==    by 0x4019C6: void std::_Destroy<std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> > >(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*, std::allocator<std::vector<Cell, std::allocator<Cell> > >&) (stl_construct.h:151)
==3526==    by 0x401908: std::vector<std::vector<Cell, std::allocator<Cell> >, std::allocator<std::vector<Cell, std::allocator<Cell> > > >::~vector() (stl_vector.h:415)
==3526==  Address 0x5a1fda0 is 0 bytes inside a block of size 32 free'd
==3526==    at 0x4C2C2BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3526==    by 0x404F4B: Cell::~Cell() (Cell.cpp:14)
==3526==    by 0x401CBC: void std::_Destroy<Cell>(Cell*) (stl_construct.h:93)
==3526==    by 0x401C85: void std::_Destroy_aux<false>::__destroy<Cell*>(Cell*, Cell*) (stl_construct.h:103)
==3526==    by 0x401C30: void std::_Destroy<Cell*>(Cell*, Cell*) (stl_construct.h:126)
==3526==    by 0x401BBC: void std::_Destroy<Cell*, Cell>(Cell*, Cell*, std::allocator<Cell>&) (stl_construct.h:151)
==3526==    by 0x401AFE: std::vector<Cell, std::allocator<Cell> >::~vector() (stl_vector.h:415)
==3526==    by 0x401AC6: void std::_Destroy<std::vector<Cell, std::allocator<Cell> > >(std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:93)
==3526==    by 0x401A8F: void std::_Destroy_aux<false>::__destroy<std::vector<Cell, std::allocator<Cell> >*>(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:103)
==3526==    by 0x401A3A: void std::_Destroy<std::vector<Cell, std::allocator<Cell> >*>(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:126)
==3526==    by 0x4019C6: void std::_Destroy<std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> > >(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*, std::allocator<std::vector<Cell, std::allocator<Cell> > >&) (stl_construct.h:151)
==3526==    by 0x401908: std::vector<std::vector<Cell, std::allocator<Cell> >, std::allocator<std::vector<Cell, std::allocator<Cell> > > >::~vector() (stl_vector.h:415)
==3526== 
==3526== Invalid read of size 4
==3526==    at 0x4E92655: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==3526==    by 0x4EF14DE: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==3526==    by 0x538D148: __run_exit_handlers (exit.c:82)
==3526==    by 0x538D194: exit (exit.c:104)
==3526==    by 0x5372ECB: (below main) (libc-start.c:321)
==3526==  Address 0x5a1d0b0 is 16 bytes inside a block of size 28 free'd
==3526==    at 0x4C2C2BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3526==    by 0x4EF14DE: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==3526==    by 0x40356A: ChessPiece::~ChessPiece() (ChessPiece.h:13)
==3526==    by 0x404F43: Cell::~Cell() (Cell.cpp:14)
==3526==    by 0x401CBC: void std::_Destroy<Cell>(Cell*) (stl_construct.h:93)
==3526==    by 0x401C85: void std::_Destroy_aux<false>::__destroy<Cell*>(Cell*, Cell*) (stl_construct.h:103)
==3526==    by 0x401C30: void std::_Destroy<Cell*>(Cell*, Cell*) (stl_construct.h:126)
==3526==    by 0x401BBC: void std::_Destroy<Cell*, Cell>(Cell*, Cell*, std::allocator<Cell>&) (stl_construct.h:151)
==3526==    by 0x401AFE: std::vector<Cell, std::allocator<Cell> >::~vector() (stl_vector.h:415)
==3526==    by 0x401AC6: void std::_Destroy<std::vector<Cell, std::allocator<Cell> > >(std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:93)
==3526==    by 0x401A8F: void std::_Destroy_aux<false>::__destroy<std::vector<Cell, std::allocator<Cell> >*>(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:103)
==3526==    by 0x401A3A: void std::_Destroy<std::vector<Cell, std::allocator<Cell> >*>(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:126)
==3526== 
==3526== Invalid write of size 4
==3526==    at 0x4E9265B: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==3526==    by 0x4EF14DE: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==3526==    by 0x538D148: __run_exit_handlers (exit.c:82)
==3526==    by 0x538D194: exit (exit.c:104)
==3526==    by 0x5372ECB: (below main) (libc-start.c:321)
==3526==  Address 0x5a1d0b0 is 16 bytes inside a block of size 28 free'd
==3526==    at 0x4C2C2BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3526==    by 0x4EF14DE: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==3526==    by 0x40356A: ChessPiece::~ChessPiece() (ChessPiece.h:13)
==3526==    by 0x404F43: Cell::~Cell() (Cell.cpp:14)
==3526==    by 0x401CBC: void std::_Destroy<Cell>(Cell*) (stl_construct.h:93)
==3526==    by 0x401C85: void std::_Destroy_aux<false>::__destroy<Cell*>(Cell*, Cell*) (stl_construct.h:103)
==3526==    by 0x401C30: void std::_Destroy<Cell*>(Cell*, Cell*) (stl_construct.h:126)
==3526==    by 0x401BBC: void std::_Destroy<Cell*, Cell>(Cell*, Cell*, std::allocator<Cell>&) (stl_construct.h:151)
==3526==    by 0x401AFE: std::vector<Cell, std::allocator<Cell> >::~vector() (stl_vector.h:415)
==3526==    by 0x401AC6: void std::_Destroy<std::vector<Cell, std::allocator<Cell> > >(std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:93)
==3526==    by 0x401A8F: void std::_Destroy_aux<false>::__destroy<std::vector<Cell, std::allocator<Cell> >*>(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:103)
==3526==    by 0x401A3A: void std::_Destroy<std::vector<Cell, std::allocator<Cell> >*>(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:126)
==3526== 
==3526== Invalid free() / delete / delete[] / realloc()
==3526==    at 0x4C2C2BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3526==    by 0x4EF14DE: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==3526==    by 0x538D148: __run_exit_handlers (exit.c:82)
==3526==    by 0x538D194: exit (exit.c:104)
==3526==    by 0x5372ECB: (below main) (libc-start.c:321)
==3526==  Address 0x5a1d0a0 is 0 bytes inside a block of size 28 free'd
==3526==    at 0x4C2C2BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3526==    by 0x4EF14DE: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==3526==    by 0x40356A: ChessPiece::~ChessPiece() (ChessPiece.h:13)
==3526==    by 0x404F43: Cell::~Cell() (Cell.cpp:14)
==3526==    by 0x401CBC: void std::_Destroy<Cell>(Cell*) (stl_construct.h:93)
==3526==    by 0x401C85: void std::_Destroy_aux<false>::__destroy<Cell*>(Cell*, Cell*) (stl_construct.h:103)
==3526==    by 0x401C30: void std::_Destroy<Cell*>(Cell*, Cell*) (stl_construct.h:126)
==3526==    by 0x401BBC: void std::_Destroy<Cell*, Cell>(Cell*, Cell*, std::allocator<Cell>&) (stl_construct.h:151)
==3526==    by 0x401AFE: std::vector<Cell, std::allocator<Cell> >::~vector() (stl_vector.h:415)
==3526==    by 0x401AC6: void std::_Destroy<std::vector<Cell, std::allocator<Cell> > >(std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:93)
==3526==    by 0x401A8F: void std::_Destroy_aux<false>::__destroy<std::vector<Cell, std::allocator<Cell> >*>(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:103)
==3526==    by 0x401A3A: void std::_Destroy<std::vector<Cell, std::allocator<Cell> >*>(std::vector<Cell, std::allocator<Cell> >*, std::vector<Cell, std::allocator<Cell> >*) (stl_construct.h:126)
==3526== 
==3526== 
==3526== HEAP SUMMARY:
==3526==     in use at exit: 0 bytes in 0 blocks
==3526==   total heap usage: 292 allocs, 294 frees, 11,462 bytes allocated
==3526== 
==3526== All heap blocks were freed -- no leaks are possible
==3526== 
==3526== For counts of detected and suppressed errors, rerun with: -v
==3526== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0)

1 个答案:

答案 0 :(得分:2)

Cell打破Rule of Three。它试图“拥有”一个原始指针,在其析构函数中删除其目标,但是无法正确复制,因此两个Cell对象都会尝试删除相同的ChessPiece

选项包括:

  • 如果单元格应该“拥有”该单元,则使用智能指针(或编写复制构造函数和复制赋值运算符来正确处理原始指针);
  • 不要让单元格试图删除该单块,如果它不应该“拥有”它;
  • 使用boost::optional之类的内容,允许单元格可选地包含没有动态分配的部分。