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

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

int* ary = new int[Size]

but

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

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

int ary[sizeY][sizeX] 

所做的事。


当前回答

如果行长是编译时常数,c++ 11允许

auto arr2d = new int [nrows][CONSTANT];

请看这个答案。像gcc这样的编译器允许将变长数组作为c++的扩展,可以使用如下所示的new来获得完全的运行时可变数组维度功能,就像C99所允许的那样,但是可移植的ISO c++仅限于第一个维度是变量。

另一个有效的选择是手动对一个大的1d数组进行2d索引,正如另一个答案所示,允许与真正的2d数组相同的编译器优化(例如,证明或检查数组不会彼此别名/重叠)。


否则,您可以使用指向数组的指针数组来支持类似连续2D数组的2D语法,尽管这不是一个有效的单一大分配。你可以使用循环初始化它,就像这样:

int** a = new int*[rowCount];
for(int i = 0; i < rowCount; ++i)
    a[i] = new int[colCount];

上面,对于colCount= 5和rowCount = 4,将产生以下结果:

在删除指针数组之前,不要忘记使用循环单独删除每一行。另一个答案中的例子。

其他回答

这个问题一直困扰着我——这是一个很常见的问题,应该已经有了一个好的解决方案,比向量的向量或滚动你自己的数组索引更好的解决方案。

当c++中应该存在一些东西,但却不存在时,第一个地方是boost.org。在那里我找到了Boost多维数组库,multi_array。它甚至包括一个multi_array_ref类,可用于包装您自己的一维数组缓冲区。

试着这样做:

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

如果你想要一个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。

我建议使用2D向量而不是2D数组。基本上尽可能使用向量主要是因为

动态内存分配没有麻烦 自动内存管理

下面是一个小代码片段,您可以在其中创建一个动态大小的数组

vector<vector<int>> arr;
for (int i=0; i<n; i++)
{    
    vector<int> temp;
    for (int j=0; j<k; j++)
    {
        int val;
        //assign values
        temp.push_back(val);
    }
    arr.push_back(temp);
}

Typedef是你的朋友

在回顾并查看了许多其他答案之后,我发现需要进行更深层次的解释,因为许多其他答案要么存在性能问题,要么迫使您使用不寻常的或繁重的语法来声明数组,或访问数组元素(或以上所有问题)。

首先,这个答案假设您在编译时知道数组的尺寸。如果你这样做,那么这是最好的解决方案,因为它将提供最好的性能,并允许您使用标准数组语法来访问数组元素。

The reason this gives the best performance is because it allocates all of the arrays as a contiguous block of memory meaning that you are likely to have less page misses and better spacial locality. Allocating in a loop may cause the individual arrays to end up scattered on multiple non-contiguous pages through the virtual memory space as the allocation loop could be interrupted ( possibly multiple times ) by other threads or processes, or simply due to the discretion of the allocator filling in small, empty memory blocks it happens to have available.

其他好处是声明语法简单,数组访问语法标准。

在c++中使用new:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {

typedef double (array5k_t)[5000];

array5k_t *array5k = new array5k_t[5000];

array5k[4999][4999] = 10;
printf("array5k[4999][4999] == %f\n", array5k[4999][4999]);

return 0;
}

或使用calloc的C样式:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {

typedef double (*array5k_t)[5000];

array5k_t array5k = calloc(5000, sizeof(double)*5000);

array5k[4999][4999] = 10;
printf("array5k[4999][4999] == %f\n", array5k[4999][4999]);

return 0;
}