我如何使用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= 5
和rowCount = 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