Ответ 1
Если у вас действительно есть двумерный массив, этот вызов memcpy
будет работать. Но вы этого не сделаете, у вас есть width
отдельных несмежных 1-D массивы, собранные в массиве указателей.
Можно динамически выделять непрерывный блок, в котором количество строк и столбцов изменяется во время выполнения и сохраняет двухскриптовый доступ. Вам придется изменить код распределения следующим образом:
GridUnit** newGrid;
newGrid = new GridUnit*[width];
newGrid[0] = new GridUnit[width * height];
for (int i = 1; i < width; i++)
newGrid[i] = newGrid[i-1] + height;
Распределение становится проще:
delete[] newGrid[0];
delete[] newGrid;
Там нет delete[]
для newGrid[i]
с i > 0
потому что у них нет своих собственных блоков, они просто указывают на один большой блок. Поскольку все смежно, вы можете думать о newGrid[0]
либо как указатель на первую строку (элементы height
), либо как весь двумерный массив (элементы width * height
).
И тогда вы можете получить доступ ко всем данным в виде единого непрерывного блока:
memcpy(newGrid[0], oldGrid[0], height * width * sizeof newGrid[0][0]);
Конечно, не следует использовать необработанные указатели для владения памятью. Умный указатель обеспечит правильное удаление памяти даже при исключительном контроле потока. Это будет выглядеть так:
std::unique_ptr<GridUnit[]> newData;
std::unique_ptr<GridUnit*[]> newGrid;
newData.reset(new GridUnit[width * height]);
// or newData = std::make_unique<GridUnit[]>(width * height);
newGrid.reset(new GridUnit*[width]);
// or newGrid = std::make_unique<GridUnit*[]>(width);
for (int i = 0; i < width; i++)
newGrid[i] = &newData[i * height];