Copy 2D array using memcpy?
If you actually had a 2-D array, that memcpy call would work. But you don't, you have width separate discontiguous 1-D arrays, collected in an array of pointers.
It is possible to dynamically allocate a contiguous block where row and column count both vary at runtime, and preserve the two-subscript access. You'll have to change the allocation code as follows:
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;
Deallocation becomes simpler:
delete[] newGrid[0];
delete[] newGrid;
There's no delete[] for newGrid[i] with i > 0 because they don't have their own blocks, they just point into the single large block. Because everything is contiguous, you can think of newGrid[0] either as a pointer to the first row (height elements), or the entire 2-D array (width * height elements).
And you can then access all the data as a single contiguous block:
memcpy(newGrid[0], oldGrid[0], height * width * sizeof newGrid[0][0]);
Of course, one shouldn't use raw pointers for memory ownership. A smart pointer will ensure the memory is properly deleted even with exceptional flow control. It would look like this:
std::unique_ptr<GridUnit[]> newData;
std::unique_ptr<GridUnit*[]> newGrid;
// before C++14 use // newData.reset(new GridUnit[width * height]);
newData = std::make_unique<GridUnit[]>(width * height);
// before C++14 use // newGrid.reset(new GridUnit*[width]);
newGrid = std::make_unique<GridUnit*[]>(width);
for (int i = 0; i < width; i++)
newGrid[i] = &newData[i * height];
Admin
Updated on June 15, 2022Comments
-
Admin 12 monthsSo I want to copy the contents of a 2D array to another array of the exact same type. Here is how the array is created:
GridUnit** newGrid; newGrid = new GridUnit*[width]; for (int i = 0; i < width; i++) newGrid[i] = new GridUnit[height];GridUnit is size 16 (4 floats). So that's all initialised fine, no problems with using it as it is after I have ran the for loops to actually fill the values with some data. Now what I want to do is copy the contents of another array into this one (without for loops if possible). This is what I have been trying to do so far:
memcpy(&newGrid, &grid, height * width * 16);'grid' is identical to 'newGrid' in terms of its size and type. However, this does not work. I know the memcpy is possibly not correct, but having tried multiple different setups using this, I don't know what's going wrong with it anymore, so any help would be welcome!
-
Admin about 8 yearsOh of course, can't believe I didn't realise that. Makes a lot of sense why it wasn't working now. However, I don't see a resolution short of using for loops if I still want to use this array setup? -
Support Ukraine about 8 yearsIf height is a constant, it can be done, i.e getting a 2D array with new. But is it? -
Support Ukraine about 8 years@KieronH See stackoverflow.com/questions/936687/… for more information -
Ben Voigt about 8 years@KieronH: I edited in an approach that I think you might find useful. -
Admin about 8 yearsWow, thanks! This is exactly what I was looking for! -
UserX almost 3 yearsWow, that's ingenious! -
Ayxan Haqverdili over 2 yearsThis is great. Better yet if you wrap around aMatrixclass or get a library that does.