2014-05-17 71 views
0

我试着调试下面的代码,并且出现“访问冲突”错误。我不明白为什么第二个循环在访问第二行元素时失败,而第一个循环能够访问所有元素。2D阵列访问冲突

我搞砸了*,&[],但无法弄清楚。

谢谢。

#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; 
} 
+0

你能解释一下你想要做的更多吗?有点不清楚。 – Ben

+0

真正的问题在这里:(&data)[i]。由于数据是参数中的单个元素,因此&data是指向单个元素的指针。这意味着i> 0是一个问题。多维数组实际上是一块内存,当你在多维数组上进行[i] [j]操作时,编译器将其与[i] [j]中的指针数组区别开来。多维数组上的[i] [j]与[i * numcolumns + j]相同。 – thang

回答

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]) { 

所以它适用于所有二维数组。

+0

在传递参数 - 'a(arr,2 * 5,5);'并在参数中指定大小时删除星号,同样在访问数据时删除和号,我可以使用两个下标操作符。 我不认为这是超出界限,因为第一个循环能够访问相同的内存;这是我在第一句话的第一部分回答的问题。但是,我仍然不明白“丢失所有类型信息”的含义。你可以请扩展一下,或者分享一些我可以阅读更多内容的来源。谢谢。 – user2570380

+0

@ user2570380:当你说'a [1] [2]'时(例如),你需要类型系统以便将a [1]解析到正确的地址(它是数组1的元素0) 。这是因为地址取决于第二维的*大小*。如果你有一个2x5的'int'数组,第一个下标中的每个增量必须“跳”5个“int”值。您只能使用与运行时类型匹配的静态类型来执行此操作。如果你只有一个'int *',那么编译器或CPU应该怎么知道它应该用'a [1] [2]'做什么? – bitmask

1

*arr等于*(arr + 0)等于arr[0]arr[0]只有5 nElements,而不是10这样调用该函数:

a(*arr, 5, 5); 
2

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

你正在寻找的语法是:

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

*当然是乘法,而不是引用操作的。当调用这个函数时,通过将数组视为一个10元素的1维数组来处理它,所以你需要使用算术来计算出所需的索引。

最后,在函数调用中,*arr应该是(int *)&arr(int *)arr。你实际写的是arr[0],它是一个5元素的数组。在您的函数中尝试读取5个以上的元素是一种超出界限的访问方式。在实践中,出于效率原因,编译器不会尝试检测出界限以外的访问,并且它似乎可以工作。

1

变化在双行for循环:

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