无法在 C++ 中声明动态二维数组 [重复]
Posted
技术标签:
【中文标题】无法在 C++ 中声明动态二维数组 [重复]【英文标题】:Can't declare dynamic 2D array in C++ [duplicate] 【发布时间】:2013-12-17 05:39:25 【问题描述】:我遇到了一个问题 - 我无法在 C++ 中使用由用户编写的整数声明二维数组。
这段代码运行良好-
cin>>m>>n;
int *array;
array=new int[m*n];
但我做不到 -
cin>>m>>n;
int *array;
array=new int[m][n];
有什么想法可以绕过它吗? 附言错误:无法在赋值中将 'int ()[2]' 转换为 'int'。
【问题讨论】:
您不是在尝试声明一个动态数组(这在 C++ 中实际上是非法的,所有数组都必须是固定大小的)。您正在尝试分配一个动态数组。 【参考方案1】:改变
cin>>m>>n;
int *array;
array=new int[m][n];
到
cin>>m>>n;
int **array;
array=new int * [m];
for ( int i = 0; i < m; i++ ) array[i] = new int[n];
【讨论】:
谢谢,这对我有用。 不要忘记删除所有已分配的指针。 不要忘记解释你的答案,而不是将代码有害地转储给不理解它的人。【参考方案2】:array
是 int *
并且您尝试分配 int **
... 将数组更改为 int**
。
二维数组实际上是数组的数组,所以需要指针指向。
【讨论】:
好吧,数组不是指针,它们只是在使用时衰减指向指针。因此,声明为int array[m][n]
的数组不是指向指针的指针,而是长度为n 的m 个连续的slab。不涉及指针数组。
@cmaster 数组不是指针,但是问题中的变量array
是非常指针的。请再读一遍,我只是说他需要指向指针的指针!
不,你不能有一个指向数组的指针的指针。类型和元素布局都不兼容。【参考方案3】:
那是因为你只能使用new
来分配一维数组。事实上,二维数组也是一维数组,在大多数系统中,所有行都是简单连接的。这称为行优先内存布局。
您可以使用一维数组来模拟二维数组。索引转换为:
index1 = y * m + x
这也比在“重复”链接或其他答案中建议的每行创建一个数组具有更好的性能。
【讨论】:
“只能用new分配一维数组”是不对的,可以分配任意类型的数组,包括数组的数组,无非就是多维数组。不信可以看看我的回答。【参考方案4】:正如 Domi 所说(但 不是 index1=y*m+x
而是 index1=x*n+y
来模拟您想要的符号):
int *array = new int [m*n];
int get (int x, int y) // emulates array[x][y] for array[m][n]
return array[x*n+y];
但是,我认为真正的二维分配(正如莫斯科的 Vlad 向您展示的那样)创建速度较慢(并且需要更多内存),但访问速度更快。因为array[x*n+y] == *(array+x*n+y)
,还是array[x][y] == *(*(array+x)+y)
,所以你少了一个乘法,但多了一个解引用,总之我认为它更快。
你也可以创建一个类:
class array2d
private:
int *data;
int mm, nn;
public:
array2d (int m, int n)
mm = m;
nn = n;
data = new int [m*n];
~array2d ()
delete[] data;
int *operator[] (int x)
return (data+x*nn);
;
你可以使用它
array2d arr(10,10);
arr[5][7] = 1;
【讨论】:
【参考方案5】:你可以这样做:
typedef int RowType[n];
RowType *array = new RowType[m];
doStuffWith(array[y][x]);
或者,更短(但更难记住):
int (*array)[n] = new (int[m][n]);
编辑:
C++ 中有一个问题,即new
运算符的数组大小必须保持不变,因此只有在n
为const
时才能执行此操作。这在 C 中不是问题(以及我忘记这一点的原因),因此即使 n 和 m 不是 const,以下内容也有效:
RowType *array = (RowType*)malloc(m * sizeof(RowType));
当然,您可以通过这样做来解决 C++ 中的这个限制,即使 m
和 n
都是动态的,它仍然有效:
RowType *array = (RowType*)new int[m * n];
typedef
免费版是这样的:
int (*array)[n] = (int (*)[n])new int[m *n];
【讨论】:
不,你不能;)如果有的话,那么 n 必须是常数,我相信这里不是这种情况。 为了能够做到这样,n 必须是常数,在这种情况下不是。 @Bartek 你是对的,C++ 中有一个问题。不是很好。 C 没有这种有趣的限制... @Bartek 找到了一种解决此 C++ 限制的方法,而无需诉诸malloc()
:-)
C 没有这个问题,因为 C 没有 new
关键字 ;) 所以既然你无论如何都在做 malloc,那么它将责任转移到较低级别的函数。除了 sizeof 类型是在运行时计算的,所以 new
关键字中没有使用的 typedef 可以毫无问题地传递给 sizeof() 函数。【参考方案6】:
首先我建议你应该使用 std::vector 来避免内存分配/释放问题。
如果你想要一个数组实现,那么你可以将数组声明为指向 int 的指针。
cin >> m >> n;
int** array = new int* [m];
for ( int I = 0; I < m; I++ )
array[I] = new int[n];
【讨论】:
谢谢,不知道向量。以上是关于无法在 C++ 中声明动态二维数组 [重复]的主要内容,如果未能解决你的问题,请参考以下文章