C++ 二维数组访问冲突

C++ 二维数组访问冲突,c++,arrays,pointers,C++,Arrays,Pointers,我试着调试下面的代码,我得到了一个“访问冲突”错误。我不明白为什么第二个循环在访问第二行元素时失败,而第一个循环能够访问所有元素 我把*、&和[]搞砸了,但我搞不清楚 谢谢 #include <iostream> void a(const int* data, unsigned int nElements, unsigned int nColumns) { for (unsigned int i = 0; i < nElements; ++i) st

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

我把
*
&
[]
搞砸了,但我搞不清楚

谢谢

#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;
}
#包括
void a(常量int*数据、无符号int元素、无符号int n列){
for(无符号整数i=0;istd::cout
*arr
等于
*(arr+0)
,它等于
arr[0]
arr[0]
只有5个
元素,而不是10个。调用如下函数:

a(*arr, 5, 5);

*arr
等于
*(arr+0)
它等于
arr[0]
arr[0]
只有5个
元素,而不是10个。按如下方式调用函数:

a(*arr, 5, 5);
(&data)[i]
显然是假的。
数据
是一个非数组的变量。写入
(&data)[0]
并将变量视为具有一个元素的数组是合法的。但是,如果
i>0
则尝试在存储
数据
的位置之后访问内存,而这不是您拥有的任何内存。(不要将指针
数据
与其指向的对象混淆)

您要查找的语法是:

std::cout << data[i * nColumns + j];
std::cout
(&data)[i]
显然是伪造的。
data
是一个非数组的变量。写入
(&data)[0]是合法的
并将变量视为一个只有一个元素的数组。但是,如果
i>0
,则尝试在存储
数据
后访问内存,而该内存不是您拥有的内存。(不要将指针
数据
与其指向的对象混淆)

您要查找的语法是:

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

std::cout将双for循环中的行更改为:

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

std::cout将双for循环中的行更改为:

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

std::cout一旦在
a
函数中,您就丢失了所有类型信息,因此无法期望下标运算符工作,因为您没有说明数组的大小。请在参数列表中指定大小,下标将起作用:

void a(int const (&data)[2][5]) {
  for (auto const& row : data)
    for (auto i : row)
      ::std::cout << i << " ";
  ::std::cout << ::std::endl;
}
void a(int const&data)[2][5]){
用于(自动常量和行:数据)
用于(自动i:行)

::std::cout一旦进入
a
函数,就会丢失所有类型信息,因此无法期望下标运算符工作,因为您没有说明数组的大小。请在参数列表中指定大小,下标将起作用:

void a(int const (&data)[2][5]) {
  for (auto const& row : data)
    for (auto i : row)
      ::std::cout << i << " ";
  ::std::cout << ::std::endl;
}
void a(int const&data)[2][5]){
用于(自动常量和行:数据)
用于(自动i:行)

::std::你能解释一下你想做什么吗?有点不清楚。真正的问题是:(&data)[i]。因为数据是参数中的单个元素,&data是指向单个元素的指针。这意味着i>0是个问题。多维数组实际上是一块内存,当你做[i][j]时在多维数组上,编译器对待它的方式与指针数组上的[i][j]不同。多维数组上的[i][j]与[i*numcolumns+j]相同。你能解释一下你想做什么吗?这有点不清楚。真正的问题是:(&data)[i]。因为数据是参数中的单个元素,&数据是指向单个元素的指针。这意味着i>0是一个问题。多维数组实际上是一块内存,当您对多维数组执行[i][j]操作时,编译器对它的处理方式与对指针数组执行[i][j]操作不同。[i][j]在多维数组上与[i*numcolumns+j]相同。在传递参数时删除星号--
a(arr,2*5,5);
,并在参数中指定大小,如您的示例中所示,在访问数据时也删除了与,我能够使用两个下标运算符。我不认为这是超出范围的,因为第一个循环能够访问相同的内存;这是我让您在第一次发送的第一部分中回答的问题然而,我仍然不明白你所说的“丢失所有类型信息”是什么意思。你能详细说明一下吗,或者分享一个我可以阅读更多有关它的资料来源。谢谢。@user2570380:当你说
a[1][2]
(例如)你需要类型系统才能将
a[1]
解析到正确的地址(即数组1的元素0)。这是因为地址取决于第二个维度的大小。如果有2x5
int
数组,则第一个下标中的每个增量都必须“跳转”5
int
值。您只能使用与运行时类型匹配的静态类型来执行此操作。如果您只有一个
int*
编译器或cpu如何知道它应该如何处理
a[1][2]
?在传递参数--
a(arr,2*5,5)时删除星号后;
,并在参数中指定大小,如您的示例中所示,在访问数据时也删除了与,我能够使用两个下标运算符。我不认为这是超出范围的,因为第一个循环能够访问相同的内存;这是我让您在第一次发送的第一部分中回答的问题然而,我仍然不明白你所说的“丢失所有类型信息”是什么意思。你能详细说明一下吗,或者分享一个我可以阅读更多有关它的资料来源。谢谢。@user2570380:当你说
a[1][2]
(例如)你需要类型系统才能将
a[1]
解析到正确的地址(即数组1的元素0)。这是因为地址取决于第二个维度的大小。如果有2x5
int
数组,则第一个下标中的每个增量都必须“跳转”5
int
值。您只能使用与运行时类型匹配的静态类型来执行此操作。如果您只有一个
int*
h