2D阵列访问冲突

时间:2014-05-17 23:22:07

标签: c++ arrays pointers

我尝试调试以下代码,并且我得到了一个"访问冲突"错误。我不明白为什么第二个循环在访问第二行元素时失败,而第一个循环能够访问所有元素。

我弄乱了*&[],但无法弄明白。

感谢。

#include <iostream>

void a(const int* data, unsigned int nElements, unsigned int nColumns) {

    for (unsigned int i = 0; i < nElements; ++i)
        std::cout << data[i];

    for (unsigned int i = 0; i < nElements / nColumns; ++i)
        for (unsigned int j = 0; j < nColumns; ++j)
            std::cout << (&data)[i][j];
}

int main() {
    int arr[2][5] = {
        { 0, 1, 2, 3, 4 },
        { 5, 6, 7, 8, 9 }
    };

    a(*arr, 2 * 5, 5);

    return 0;
}

4 个答案:

答案 0 :(得分:2)

(&data)[i]显然是假的。 data是一个不是数组的变量。编写(&data)[0]并将变量视为具有一个元素的数组是合法的。但是,如果i > 0然后您尝试在存储data之后访问内存,那么这不是您拥有的任何内存。 (不要将指针data与它指向的东西混淆)。

您正在寻找的语法是:

std::cout << data[i * nColumns + j];

这个*当然是乘法,而不是取消引用算子。在调用此功能时,您正在&#34;展平&#34;数组通过将其视为10元素1-D数组,因此您需要使用算术来计算所需的索引。

最后,在函数调用中,*arr应为(int *)&arr(int *)arr。你实际写的是arr[0],它是一个5元素的数组。它是一个超出界限的访问权限,可以尝试从函数中读取超过5个元素。实际上,由于效率原因,编译器不会尝试检测越界访问,它似乎会起作用。

答案 1 :(得分:1)

*arr等于*(arr + 0),等于arr[0]arr[0]只有5 nElements,而不是10.请按以下方式调用函数:

a(*arr, 5, 5);

答案 2 :(得分:1)

将double for循环中的行更改为:

std::cout << data[i * nColumns + j];

答案 3 :(得分:0)

一旦进入a函数,就丢失了所有类型信息,因此您不能指望下标运算符可以正常工作,因为您没有说明数组的大小。在参数列表中指定大小,下标将起作用:

void a(int const (&data)[2][5]) {
  for (auto const& row : data)
    for (auto i : row)
      ::std::cout << i << " ";
  ::std::cout << ::std::endl;
}

然后,您甚至可以疯狂地将原型更改为:

template <size_t R, size_t C>
void a(int const (&data)[R][C]) {

因此它适用于所有2D阵列。