为动态2d数组创建正确的复制构造函数

Creating proper copy constructor for a dynamic 2d array

本文关键字:复制 构造函数 创建 动态 2d 数组      更新时间:2023-10-16

调用复制构造函数时,我的程序出现seg错误。这就是我的Grid类的构造函数:

Grid::Grid(unsigned int grid_size) {
    size = grid_size;
    grid = new char *[size];
    for(int i = 0; i < size; i++) {
        grid[i] = new char[size];
    }
}

这是我的复制构造函数,它导致了问题:

Grid::Grid(Grid const &other_grid) {
    size = other_grid.size;
    grid = new char *[other_grid.size];
    for(int i = 0; i < size; i++) {
        grid[i] = new char[size];
    }
    for(int i = 0; i < size; i++) {
        for(int j = 0; j < size; j++) {
            grid[i][j] = other_grid.grid[i][j];
        }
    }
}

自毁

Grid::~Grid() {
for(int i = 0; i < size; i++) {
    delete [] grid[i];
}
delete [] grid;
}

operator=过载

Grid & Grid::operator=(Grid const &other_grid) {
size = other_grid.size;
grid = new char *[other_grid.size];
for(int i = 0; i < other_grid.size; i++) {
    for(int j = 0; j < other_grid.size; j++) {
        grid[i][j] = other_grid.grid[i][j];
    }
}
return *this;
}

不要把时间浪费在那种疯狂的手动分配上。使用std::vector

class Grid {
    Grid(unsigned int size);
private:
    std::vector<std::vector<char>> grid;
};
Grid::Grid(unsigned int size)
: grid(size, std::vector<char>(size)) {}

你可以免费获得释放和工作副本(如果你使用的是现代编译器,也可以移动)。

EDIT:重新仔细阅读您的代码。你的作业操作员坏了。你忘记了分配网格中的每一行。

另外一点:你不需要所有这些分配。你只需要一个。将grid设为char*而不是char**,并以此方式编写。我在这里省略了分配失败的检查。

Grid::Grid(unsigned int grid_size)
    :size(grid_size), grid(0)
{
    if (size > 0)
    {
        grid = new char[size*size];
    }
}
Grid::Grid(Grid const &other_grid)
    :size(0)
{
    CopyFrom(other_grid);
}
Grid::~Grid() 
{
    if (size > 0)
    {
        delete [] grid;
        grid = 0;
    }
}
Grid& Grid::operator=(Grid const &other_grid) 
{
    CopyFrom(other_grid);
    return *this;
}
void Grid::CopyFrom(Grid const &other_grid)
{
    if (size > 0) delete [] grid;
    size = newSize;
    if (newSize > 0)
    {
        grid = new char[newSize*newSize];
        memcpy(grid, other_grid.grid, newSize*newSize);
    }
    else
    {
        grid = 0;
    }
}

然后,如果你想访问网格中x,y点的一个字节,你可以这样写。(我将把适当的边界检查留给你)。

char Grid::GetByte(int x, int y)
{
    return grid[y*size + x];
}