我如何使用new在C ++中声明2d数组?

我如何使用new声明2d数组?

就像,对于一个“正常”的阵列,我会:

int* ary = new int[Size]

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

a)不工作/编译和b)没有完成:

int ary[sizeY][sizeX] 

确实。


动态2D数组基本上是指向数组的指针数组。 您可以使用循环来初始化它,如下所示:

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

以上,对于colCount= 5rowCount = 4 ,将产生以下内容:

在这里输入图像描述


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]

虽然这个流行的答案会给你你想要的索引语法,但它是双重低效率的:在空间和时间上都很大且很慢。 有一个更好的方法。

为什么答案是大而慢

建议的解决方案是创建一个动态指针数组,然后将每个指针初始化为它自己的独立动态数组。 这种方法的优点是它给了你习惯的索引语法,所以如果你想在位置x,y找到矩阵的值,你可以这样说:

int val = matrix[ x ][ y ];

这是有效的,因为矩阵[x]返回一个指向数组的指针,然后用[y]索引。 打破它:

int* row = matrix[ x ];
int  val = row[ y ];

方便,是吗? 我们喜欢我们的[x] [y]语法。

但解决方案有一个很大的缺点 ,那就是它既胖又慢。

为什么?

它既胖又慢的原因实际上是一样的。 矩阵中的每个“行”都是一个单独分配的动态数组。 进行堆分配在时间和空间上都很昂贵。 分配器需要时间进行分配,有时运行O(n)算法来完成分配。 分配器为每个行数组添加额外的字节用于簿记和对齐。 额外的空间成本...呃...额外的空间。 当您释放矩阵时,解除分配器还需要额外的时间,并精心地释放每个单独的行分配。 只是想着它而让我大汗淋漓。

还有另一个原因,它很慢。 这些单独的分配往往生活在不连续的内存部分。 一行可能在地址1000,另一行可能在地址100,000--你明白了。 这意味着,当你穿越矩阵时,你像一个狂野的人一样跳过记忆。 这往往会导致缓存未命中,从而大大减慢处理时间。

所以,如果你绝对必须有你可爱的[x] [y]索引语法,请使用该解决方案。 如果你想快速和小巧(如果你不关心这些,为什么你在使用C ++?),你需要一个不同的解决方案。

不同的解决方案

更好的解决方案是将整个矩阵分配为单个动态数组,然后使用(略)巧妙的索引数学来访问单元格。 索引数学只是非常聪明; 不,它根本不聪明:很明显。

class Matrix
{
    ...
    size_t index( int x, int y ) const { return x + m_width * y; }
};

鉴于这个index()函数(我想像的是一个类的成员,因为它需要知道矩阵的m_width ),您可以访问矩阵数组中的单元格。 矩阵数组像这样分配:

array = new int[ width * height ];

因此,在缓慢,肥胖的解决方案中这相当于:

array[ x ][ y ]

......这是一个快速,小巧的解决方案:

array[ index( x, y )]

伤心,我知道。 但你会习惯的。 你的CPU会感谢你。

链接地址: http://www.djcxy.com/p/85935.html

上一篇: How do I declare a 2d array in C++ using new?

下一篇: Writing a strided x86 benchmark