无法在 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】:

arrayint * 并且您尝试分配 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 运算符的数组大小必须保持不变,因此只有在nconst 时才能执行此操作。这在 C 中不是问题(以及我忘记这一点的原因),因此即使 n 和 m 不是 const,以下内容也有效:

RowType *array = (RowType*)malloc(m * sizeof(RowType));

当然,您可以通过这样做来解决 C++ 中的这个限制,即使 mn 都是动态的,它仍然有效:

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++ 中声明动态二维数组 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

C++中动态二维数组中的地址

需要有关 C++ 中二维数组的动态内存分配的帮助

指针对指针的动态二维数组

C++:使用函数为二维数组分配内存时出错

在 C++ 中声明可变长度二维数组的正确方法

C++二维数组离散动态和连续动态空间申请