不明白用双指针(**)创建2D动态数组

时间:2019-12-02 17:05:16

标签: c++ arrays

我在理解双指针方面有些问题。好吧,我知道这意味着“指针指向指针”。但是,当我在代码中看到它时,我只是不明白。例如:


// Create  Dynamic 2D-Array
    int **arr = new int*[rows];

    for (int i = 0; i < rows; i++)
    {
        arr[i] = new int[cols];     
    }

这是我的老师用来创建2D动态数组的代码,但我听不懂。谁能解释?例如int **arr = new int*[rows];是什么意思?或者我们在那里使用for是什么? 还有一个问题:是否可以在不使用指针的情况下创建2d动态数组?

3 个答案:

答案 0 :(得分:1)

一些发现可能对您有帮助:

  1. 指针占用内存的方式与其他任何变量相同。它与任何其他类型相似。因此,如果您为变量i绘制了一个矩形,则也可以为一个指针绘制一个矩形。

  2. 使用typedefusing创建别名并简化复杂类型的定义:

    using pointer_to_int = int*;
    
    pointer_to_int* arr = new pointer_to_int[rows]; // allocates an array of pointer_to_int (similar to new int[rows])
    
    for (int i = 0; i < rows; i++)
    {
      arr[i] = new int[cols]; // arr[i] is of type pointer_to_int
    }
    

“有没有不用指针就可以创建2d动态数组的方法?” 这取决于您要查看的级别。最后,会有一个指针。您可以使用一维数组(vector<T>,如果允许的话)并将其除以行(或列)。如果该行有3列,则第一行从索引0开始,第二行从索引3开始,第三行从索引6开始,依此类推。请参见 { {3}}

答案 1 :(得分:1)

从90年代到2011年(以及之后的一段时期)编写的代码中,您会看到很多这种类型的代码。允许使用2D数组索引访问元素的这种指针集合已由std::vector(或本例中的向量)代替。

首先要了解的是int **arr; pointer-to-int 声明一个单指针。 (也称为双指针)。无论哪种方式,您都有单指针到什么位置? (指向类型的指针,无论使用的type是什么。)

为了使该方法有用,您首先分配所需的 pointers 数量。以下内容分配了一个内存块,其中包含rows pointer-to-int 指针,并将第一个指针的地址分配给arr

int **arr = new int*[rows];

现在您有rows未初始化指针。 (例如,您有一块能够容纳rows指针的内存)。要访问arr中的每个指针,您只需使用数组索引(例如arr[2]是分配的块中的3 rd 指针。)等效的指针符号为{{1 }}。 (注意:*(arr + 2)的取消引用与指针表示法中的[..]相同)

要有用,分配的块中的每个指针必须指向保存一定数量整数的有效内存。您可以为现有的整数数组分配地址,例如

*(..)

在您的情况下,您只是在分配一个可以包含#define COLS 5 ... int myarray[COLS] = {0}; /* array of COLS integer values initialized zero */ int **arr = new int*[rows]; /* your allocation a block for rows pointers to int */ ... arr[0] = myarray; /* assigning pointer to existing block to arr[0] */ 个整数的内存块,并将该块的起始地址分配给用cols分配的块中的指针之一。这就是以下代码的作用:

int **arr = new int*[rows];

现在您的对象已完成。您有一块内存大小,因此它可以包含// Create rows pointers pointing to allocated blocks of cols integers int **arr = new int*[rows]; /* allocated block of rows pointers */ for (int i = 0; i < rows; i++) /* for each pointer */ { arr[i] = new int[cols]; /* allocate & assign block of cols int */ } 个指针,并且您已经分配了rows个可以容纳rows个整数的内存块,并分配了起始地址。每个内存块的地址,其中cols包含整数个指向分配给原始块中每个指针的整数。

由于您可以使用cols访问每个指针,其中arr[x],因此只需包含另一个索引(模拟的2D索引),您就可以访问每个内存块中的每个整数,这样{{1} }将寻址由0 <= x < rows指向arr[x][y]指向的内存块中的y 整数。等效的指针符号为arr[x]

就是这样。您为一定数量的指针分配存储空间,然后为一定数量的0 <= y < cols值分配存储空间,并为每个指针分配起始地址,以便每个指针现在都拥有(例如指向)一个指针的地址。分配的内存块保存您的值。

现在,您必须分别*(*(arr + x) + y)type个整数的每个存储块(例如循环和delete[]),然后最后一次调用cols释放包含指针的内存块。

仔细考虑,如果还有其他问题,请告诉我。

答案 2 :(得分:0)

它创建一个指针数组,该数组中的每个指针指向内存中的不同位置

+-arr--+
|      |     +---------------+
|   0  |  -> | ... cols      |
|      |     +---------------+
+------+
|      |     +---------------+
|   1  |  -> | ... cols      |
|      |     +---------------+
+------+
...

+------+
|      |     +---------------+
|rows-1|  -> | ... cols      |
|      |     +---------------+
+------+

因此它不包含连续的内存,就像您将其声明为

一样
int arr[rows][cols];