我如何使用新的二维数组的声明吗?

喜欢,我会"正常"数组︰

int* ary = new int[Size]

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

a) 不工作/编译和 b) 不能完成什么︰

int ary[sizeY][sizeX] 

没有。

2009-06-01 20:42:20
问题评论:

它只有无常,sizeX: int(*ary) [sizeX] = 新 int [sizeY] [sizeX];这是创建 int [sizeY] [sizeX] 和其中所有内存都是连续的正确方法。(我并不认为这是值得答案,因为可能您 sizeX 不是常量

我不能 belive 并回答下面的所有打所有错误并不能回答的问题,但它们是所有 upvoted。通过 Johanes Shaub 的上述评论是问题的唯一正确的答案二维数组和指针数组的数组是两个完全独立的事情,显然所有人混合组成的。

@JohannesSchaub-litb︰ 这并不是 100%正确。当然它运行,在这种情况下,但是没有一种方法,使其工作在其中的所有尺寸各不都相同,请参见stackoverflow.com/a/29375830/103167

回答:

动态的二维数组基本上是指向数组的指针数组。您应该使用这样的循环,将其初始化︰

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

上面的colCount= 5rowCount = 4,将产生以下︰

enter image description here

请记住任何用new分配在堆上创建和必须解除分配与delete,只是记住这一点而一定要从堆中删除此内存完成后用它来防止泄漏。

此外请注意,此数组的指针。不是数组。指针指向数组。对重要真正正确的术语,因为很多教程弄错太。数组的数组是连续的这不是这一

是的 T [] [N] 被称作"T [N] 数组的数组",是不完整的类型,而 T [] [] 是无效的类型 (所有除了最后一个维度必须具有已知的大小)。T [N] [M] [N] 的阵列 T 的数组 [M]",而您,T [sizeX] 是 [sizeX] 的阵列 T"其中 T 是一个指针,指向 int 创建动态二维数组工作原理如下︰ 新 int [X] [Y]。它将创建数组分配类型为 int [X] [Y]。这是"洞"在 c + + 的类型系统,因为 c + + 的普通类型系统没有数组维数的大小在编译时不知道,因此这些应用程序称为"分配类型"

有人可以解释为什么我们正在做的而不是增量后前的递增吗?

这是 super 错误。首先它不是一个二维数组,第二个数组不能释放在异常发生时。

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]

它是有点粗的重量比它需要分配比需要的更多块。多维数组只需要一个内存块,而不需要每行一个块。分配一个块使得清理方便,太。

@Kevin︰ 分配就是一个连续块是转 (较少影响分配器、 更好的位置等) 的方法。但是,您不必牺牲干净的下标。请参见stackoverflow.com/a/29375830/103167

它不应该是i*sizeX+j如果我记得正确,与行主要排序应行 * numColumns + col。

在 C + + 11 是可能的︰

auto array = new double[M][N]; 

这种方式,未初始化的内存。若要初始化它这样改为︰

auto array = new double[M][N]();

示例程序 (使用编译"g + + 的标准 = c + + 11"):

#include <iostream>
#include <utility>
#include <type_traits>
#include <typeinfo>
#include <cxxabi.h>
using namespace std;

int main()
{
    const auto M = 2;
    const auto N = 2;

    // allocate (no initializatoin)
    auto array = new double[M][N];

    // pollute the memory
    array[0][0] = 2;
    array[1][0] = 3;
    array[0][1] = 4;
    array[1][1] = 5;

    // re-allocate, probably will fetch the same memory block (not portable)
    delete[] array;
    array = new double[M][N];

    // show that memory is not initialized
    for(int r = 0; r < M; r++)
    {
        for(int c = 0; c < N; c++)
            cout << array[r][c] << " ";
        cout << endl;
    }
    cout << endl;

    delete[] array;

    // the proper way to zero-initialize the array
    array = new double[M][N]();

    // show the memory is initialized
    for(int r = 0; r < M; r++)
    {
        for(int c = 0; c < N; c++)
            cout << array[r][c] << " ";
        cout << endl;
    }

    int info;
    cout << abi::__cxa_demangle(typeid(array).name(),0,0,&info) << endl;

    return 0;
}

输出︰

2 4 
3 5 

0 0 
0 0 
double (*) [2]

我需要做这类中,因此不能使用自动。正确的数组类型是什么?

您可以使用此二︰using arr2d = double(*)[2]; arr2d array = new double[M][N];

+ 1︰ 这是 OP 的要求的。正确的类型,这是double (*)[M][N]double(*)[][N]与 M,N 是常量表达式。

使用此解决方案的问题在于尺寸值不能为运行时,但应在编译时已知。

如何将 twodimensional 数组传递给 funcions 在 c + + (或 C + + 11)?C11 标准中可以做喜欢的 fn (int 列,int 行 int array[col][row]): stackoverflow.com/questions/16004668/...

尽管此流行的回答将为您提供您所需的索引语法,它是双重效率低下︰ 大且速度慢,在空间和时间两个。没有更好的方法。

为什么,答案很大和慢速

建议的解决方案是创建一个动态数组的指针,然后初始化每个指针,它指向自己的、 独立的动态数组。这种方法的优点是,它使您可以是,常用的索引语法,如果您想要查找的值 x 的位置矩阵 y,则说︰

int val = matrix[ x ][ y ];

这样做的原因矩阵 [x] 将指针返回到一个数组,然后创建索引与 [y]。打破它︰

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

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

但解决方案有一个大缺点,即它是 fat 和缓慢。

为什么?

它是 fat 和缓慢的原因实际上是相同的。矩阵中的每个"行"是单独分配的动态数组。使堆分配成本较高,同时在时间和空间。分配程序需要花费时间进行分配,有时运行 o (n) 算法来执行此操作。并分配器"填充"每行阵列与簿记和对齐的额外字节。这些额外的空间成本...嗯...额外的空间。Deallocator 将需要额外时间去解除分配矩阵、 辛苦地释放 ing 上每个单独的行分配时。获取我只要一想到它轻松中。

还有另一个原因是速度慢。这些单独的分配往往生活在不连续的内存部分。一个行可能在地址 1000,另一个位于地址 100000 — 您已领会了要旨。这意味着,当您正在遍历矩阵,您正在跳跃的像一个疯狂的人一样的内存中。这往往会导致缓存未命中,极大降低处理时间。

因此,如果您绝对必须可爱 [x] [y] 索引语法,使用该解决方案。如果您希望 quickness 和 smallness (如果您并不关心那些,为什么您正在使用 c + +?),您需要另一种解决方案。

另一种解决方案

更好的解决方案是,作为一个动态数组,然后使用聪明 (稍微) 索引数学您自己要访问的单元格分配您整个矩阵。索引的数学只是轻微地聪明;不,它不聪明根本︰ 很明显。

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

给出该index()函数 (它我期待会类的成员,因为它需要知道您的矩阵m_width ),可以访问矩阵数组中的单元格。该矩阵数组是这样分配的︰

array = new int[ width * height ];

因此这缓慢、 fat 解决方案中等效︰

array[ x ][ y ]

.是否在快速、 较小的解决方案︰

array[ index( x, y )]

悲伤,我知道。但是,您将学会使用它。和您的 CPU 将感谢您。

我很惊讶,这不会有更多的 upvotes、 答得好 !

完全没有看到这。因此,array是原始的不是Matrix类型的内容?然后, m_width的工作原理这里?并不是static此外,如果我们要使数组,为什么不实施.at(j, i)成员函数相反?答得好; 否则为 (特别是 '请不要 ptr 指针位; 已有的问题分配方案中,因此我同意)。

@Noein,我有点草绘一个解决方案不规定一个特定的情况下。更多详细信息如下所示︰class Matrix { int* array; int m_width; public: Matrix( int w, int h ) : m_width( w ), array( new int[ w * h ] ) {} ~Matrix() { delete[] array; } int at( int x, int y ) const { return array[ index( x, y ) ]; } protected: int index( int x, int y ) const { return x + m_width * y; } };如果您出该代码弄直它可能有意义,并可能搞清楚上面的答案。

我以为从您所需的矩形数组,一个不交错的静态数组示例。您可以使用以下方法︰

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

然后您可以访问的元素︰

ary[y*sizeX + x]

别忘了在使用删除 []ary.

这是一个好的方法去做。您还可以执行与大小 sizeX 矢量 < int > * sizeY 的一些不错的额外安全。

最好的做法是要将这段代码包装在类-析构函数可以执行清理,而不是强制用户通过自己做乘法,可以实现 (x,y) 的方法 get 和 set (x,y,val)。实现的 operator [] 是更棘手,但我相信有可能。

好,连续 !

内容来源于Stack Overflow How do I declare a 2d array in C++ using new?
请输入您的翻译

How do I declare a 2d array in C++ using new?

确认取消