我如何声明一个2d数组使用新?

比如,对于一个“普通”数组,我将:

int* ary = new int[Size]

but

int** ary = new int[sizeY][sizeX]

A)不工作/编译b)没有完成什么:

int ary[sizeY][sizeX] 

所做的事。


当前回答

2D数组基本上是一个指针的1D数组,其中每个指针都指向一个1D数组,该数组将保存实际数据。

这里N是行,M是列。

动态分配

int** ary = new int*[N];
  for(int i = 0; i < N; i++)
      ary[i] = new int[M];

fill

for(int i = 0; i < N; i++)
    for(int j = 0; j < M; j++)
      ary[i][j] = i;

打印

for(int i = 0; i < N; i++)
    for(int j = 0; j < M; j++)
      std::cout << ary[i][j] << "\n";

free

for(int i = 0; i < N; i++)
    delete [] ary[i];
delete [] ary;

其他回答

int** ary = new int[sizeY][sizeX]

应该是:

int **ary = new int*[sizeY];
for(int i = 0; i < sizeY; ++i) {
    ary[i] = new int[sizeX];
}

然后清理是:

for(int i = 0; i < sizeY; ++i) {
    delete [] ary[i];
}
delete [] ary;

编辑:正如Dietrich Epp在评论中指出的那样,这并不是一个轻量级的解决方案。另一种方法是使用一个大内存块:

int *ary = new int[sizeX*sizeY];

// ary[i][j] is then rewritten as
ary[i*sizeY+j]

试着这样做:

int **ary = new int* [sizeY];
for (int i = 0; i < sizeY; i++)
    ary[i] = new int[sizeX];

这个答案的目的不是添加其他答案没有涵盖的新内容,而是扩展@Kevin Loney的答案。

你可以使用轻量级声明:

int *ary = new int[SizeX*SizeY]

访问语法将是:

ary[i*SizeY+j]     // ary[i][j]

但这对大多数人来说都很麻烦,可能会导致混乱。所以,你可以这样定义宏:

#define ary(i, j)   ary[(i)*SizeY + (j)]

现在可以使用非常相似的语法ary(i, j) //表示ary[i][j]。 这具有简单美观的优点,同时,使用表达式代替索引也更简单,不那么令人困惑。

要访问,比如说,ary[2+5][3+8],你可以写ary(2+ 5,3 +8),而不是看起来复杂的ary[(2+5)*SizeY +(3+8)],也就是说,它节省了括号,有助于可读性。

警告:

尽管语法非常相似,但并不相同。 如果将数组传递给其他函数,则必须以相同的名称传递SizeY(或者声明为全局变量)。

或者,如果你需要在多个函数中使用数组,那么你可以在宏定义中添加SizeY作为另一个参数,如下所示:

#define ary(i, j, SizeY)  ary[(i)*(SizeY)+(j)]

你懂的。当然,这会变得太长而没有用处,但它仍然可以防止+和*的混淆。

当然不推荐这样做,大多数有经验的用户会谴责这是一种糟糕的做法,但我还是忍不住要分享它,因为它很优雅。

编辑: 如果你想要一个适用于任意数量数组的可移植解决方案,你可以使用以下语法:

#define access(ar, i, j, SizeY) ar[(i)*(SizeY)+(j)]

然后你可以使用访问语法将任意大小的数组传递给调用:

access(ary, i, j, SizeY)      // ary[i][j]

附注:我已经测试了这些,在g++14和g++11编译器上可以使用相同的语法(作为左值和右值)。

动态声明2D数组:

    #include<iostream>
    using namespace std;
    int main()
    {
        int x = 3, y = 3;

        int **ptr = new int *[x];

        for(int i = 0; i<y; i++)
        {
            ptr[i] = new int[y];
        }
        srand(time(0));

        for(int j = 0; j<x; j++)
        {
            for(int k = 0; k<y; k++)
            {
                int a = rand()%10;
                ptr[j][k] = a;
                cout<<ptr[j][k]<<" ";
            }
            cout<<endl;
        }
    }

现在,在上面的代码中,我们获取了一个双指针,并为它分配了一个动态内存,并给出了列的值。这里分配的内存仅用于列,现在对于行,我们只需要一个for循环,并为每一行分配一个动态内存。现在我们可以像使用2D数组一样使用指针。在上面的例子中,我们将随机数分配给我们的2D数组(指针)。这都是关于二维数组的DMA。

如果你想要一个2d的整数数组,它的元素在内存中是按顺序分配的,你必须像这样声明它

int (*intPtr)[n] = new int[x][n]

你可以用任何维数来代替x,但是n在两个地方必须相等。例子

int (*intPtr)[8] = new int[75][8];
intPtr[5][5] = 6;
cout<<intPtr[0][45]<<endl;

必须打印6。