了解2D数组的副本

时间:2017-03-06 08:25:46

标签: c++ multidimensional-array copy

我试图通过使用临时数组来切换2D数组的cols和行,并在最后使用std :: copy替换原始数组。但是std :: Copy只复制第一行和其余部分在原始数组中显示相同的旧值。语句array = {};没有将索引清除为0。

// Clear array to 0 (issue: This has no effect at all)    
array[arrayRowSize][arrayColSize] = {};

// Copy array (issue: only first row is copied, rest of original still has old values)
std::copy(&tempArray[0][0], (&tempArray[0][0])+arrayColSize*arrayRowSize, &array[0][0]);

任何人都可以查看我的代码并告诉我我做错了什么吗?请添加一些有关其实际工作方式的详细信息,并建议我们是否可以改进。

#include <iostream>
#include <cstdint>

using namespace std;

bool IsIntegerInputValid (int16_t arrayData, int8_t arrayLimit)
{
    // Entered input is a non-digit, negative number or > arrayLimit ?
    if ( cin.fail() || arrayData < 0 || arrayData > arrayLimit )
    {
        // Clear error flag and input buffer
        cin.clear();
        cin.ignore();
        cout << "Invalid input, Please try again" << endl;
        return false;
    }
    return true;
}

int main()
{
    const uint8_t kMaxArraySize = 10;
    int16_t array[kMaxArraySize][kMaxArraySize] = {};

    int16_t arrayRowSize = 0;
    int16_t arrayColSize = 0;

    // Get array size
    while (1)
    {
        cin >> arrayRowSize;
        if ( IsIntegerInputValid ( arrayRowSize, kMaxArraySize) )
        {
            while (1)
            {
                cin >> arrayColSize;
                if ( IsIntegerInputValid ( arrayColSize, kMaxArraySize) )
                {
                    break; // Got valid size
                }
            }
            break; // Got valid size
        }
    }

    // Get array input
    for (int i = 0; i < arrayRowSize; ++i)
    {
        for (int j = 0; j < arrayColSize; ++j)
        {
            cin >> array[i][j];
            if ( !IsIntegerInputValid (array[i][j], kMaxArraySize) )
            {
                --i; // Try again
            }
        }
    }

    // Copy rows to cols and cols to rows
    int16_t tempArray[kMaxArraySize][kMaxArraySize] = {};
    for (int i = 0; i < arrayColSize; ++i)
    {
        for (int j = 0; j < arrayRowSize; ++j)
        {
            tempArray[i][j] = array[j][i];
            cout << tempArray[i][j] << ' ';
        }
        cout << endl;
    }
    array[arrayRowSize][arrayColSize] = {}; // Clear array to 0 (issue: This has no effect at all)

    // Copy array (issue: only first row is copied, rest of original still has old values)
    std::copy(&tempArray[0][0], (&tempArray[0][0])+arrayColSize*arrayRowSize, &array[0][0]);

    return 0;
}

由于

2 个答案:

答案 0 :(得分:3)

array[arrayRowSize][arrayColSize] = {}; // Clear array to 0 (issue: This has no effect at all)

这将访问array的下一个出界行以及该行的下一个出界点之外的表元素(如果该行有任何不超出边界的列)。行为未定义。可以访问的最后一个索引是array[arrayRowSize - 1][arrayColSize - 1]。分配给一个超出界限的元素在清除数组时没有任何作用。

要将数组的所有元素设置为零,我会使用:

std::memset(array, 0, sizeof array);

那就是说,你即将覆盖所有价值观,所以这似乎毫无意义。

std::copy(&tempArray[0][0], (&tempArray[0][0])+arrayColSize*arrayRowSize, &array[0][0]);

这假定行连续存储在内存中。如果这是真的,这将工作得很好。但是,由于您已经分配了一个大型数组,并且只使用了每一行的一部分,因此行之间存在未使用的部分。

示例:您分配一个7x7阵列,然后在其中仅使用一个3x3阵列。内存布局可能如下:

|-----| <- a row
AAAXXXXBBBXXXXCCCX...
|-------| <- first 9 elements
A represents first row, B represents second ...
X represents unused part of the array.

现在,如果你复制9个连续元素就像它们是数组的所有元素一样,你会得到AAAXXXXBB,其中包含大量未使用的元素,而不是所有使用过的元素。

由于您的行不是连续的,因此必须分别复制每一行。或者您可以复制整个阵列,包括未使用的部分。

答案 1 :(得分:0)

副本不起作用,因为你的aray大小与kMaxArraySize不同。

copy尝试将数组复制为一维数组。但在你的情况下,2d数组转换为1d可以在里面有很多零。 如果你选择了3号,则你的阵列就像:

1 2 3 0 0 0 0 0 0 0
4 5 6 0 0 0 0 0 0 0
7 8 9 0 0 0 0 0 0 0
......

表示1d表示:

1 2 3 0 0 0 0 0 0 0 4 5 6 0 0 0 0 0 0 0 7 8 9 0 0 0 0 0 0

但副本只会有9首记录。