Создание правильного конструктора копирования для динамического 2d массива - PullRequest
1 голос
/ 17 января 2012

Моя программа вызывает ошибки при вызове конструктора копирования. Вот как выглядит мой конструктор для моего класса 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];
        }
    }
}

Destructor

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

delete [] grid;
}

оператор = перегрузка

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;
}

Ответы [ 2 ]

4 голосов
/ 17 января 2012

Не тратьте свое время на такое безумие ручного распределения.Используйте 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)) {}

И вы получите освобождение и рабочие копии (и тоже перемещаетесь, если вы используете современный компилятор) бесплатно.

1 голос
/ 17 января 2012

РЕДАКТИРОВАТЬ: перечитайте ваш код более внимательно. Ваш оператор назначения не работает. Вы забыли выделить каждую строку в сетке, которую вы назначаете.

Отдельный пункт: вам не нужны все эти распределения. Вам нужен только один. Сделайте grid a 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];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...