Copy 2D array using memcpy?

后端 未结 1 960
萌比男神i
萌比男神i 2020-12-01 08:40

So 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 G         


        
相关标签:
1条回答
  • 2020-12-01 09:21

    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];
    
    0 讨论(0)
提交回复
热议问题