初始化到多维数组的动态指针的正确方法?

时间:2013-08-16 12:28:44

标签: c++ pointers dynamic c++11 multidimensional-array

当我将它们范围扩大到2维及更高时,我一直运气不好用动态指针。例如,我想要一个指向2D数组的指针。我知道:

int A[3][4];
int (*P)[4] = A;

完全合法(即使我不完全理解为什么)。考虑到:

int *P = new int[4];

有效,我想:

int **P = new int[5][7];

也会奏效,但事实并非如此。此代码说明错误:

Error: A value of type "(*)[7]" cannot be used to initialize an entity of
       type "int **"

通过看到这个,新的部分变成了一个指向我所做的7个整数数组的指针:

int (*P)[4] = new int[7][4];

这确实有效,但这不是我想要完成的。通过这样做我至少限制为任何后续维度使用常量值,但我希望它在运行时完全定义,因此“动态”。

我怎么能让这个多维指针工作?

4 个答案:

答案 0 :(得分:65)

让我们从一些基本的例子开始。

当您说int *P = new int[4];

  1. new int[4];调用operator new function()
  2. 为4个整数分配内存。
  3. 返回对此内存的引用。
  4. 绑定此引用,您需要具有与返回引用相同类型的指针,以便您执行

    int *P = new int[4]; // As you created an array of integer
                         // you should assign it to a pointer-to-integer
    
  5. 对于多维数组,您需要分配一个指针数组,然后使用指向数组的指针填充该数组,如下所示:

    int **p;
    p = new int*[5]; // dynamic `array (size 5) of pointers to int`
    
    for (int i = 0; i < 5; ++i) {
      p[i] = new int[10];
      // each i-th pointer is now pointing to dynamic array (size 10)
      // of actual int values
    }
    

    这是它的样子:

    enter image description here

    释放内存

    1. 对于一维数组,

       // need to use the delete[] operator because we used the new[] operator
      delete[] p; //free memory pointed by p;`
      
    2. 对于2D阵列,

      // need to use the delete[] operator because we used the new[] operator
      for(int i = 0; i < 5; ++i){
          delete[] p[i];//deletes an inner array of integer;
      }
      
      delete[] p; //delete pointer holding array of pointers;
      
    3. 避免内存泄漏和悬空指针

答案 1 :(得分:6)

你想要这样的东西:

int **P = new int*[7];
p[0] = new int[5];
p[1] = new int[5];
...

答案 2 :(得分:2)

另一种方法是使用1D阵列作为2D阵列。这样你只需要分配一次内存(一个连续的块);

int *array;
size_t row=5,col=5;
array = (int*)malloc(row*col*sizeof(int)) //or new int[row*col]

这将导致与“int array [5] [5]”相同。

访问您刚刚执行的字段:

array[1 //the row you want
 * col //the number of columns
+2//the column you want
] = 4;

这等于:

array[1][2];

答案 3 :(得分:2)

这会对某些调试编译器执行边界检查,使用动态大小并自动删除自身。唯一的问题是x和y是相反的方式。

std::vector<std::vector<int>> array2d(y_size, std::vector<int>(x_size));

for (int y = 0; y < y_size; y++)
{
    for (int x = 0; x < x_size; y++)
    {
        array2d[y][x] = 0;
    }
}