我如何声明一个2d数组使用新?

比如,对于一个“普通”数组,我将:

int* ary = new int[Size]

but

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

A)不工作/编译b)没有完成什么:

int ary[sizeY][sizeX] 

所做的事。


当前回答

在某些情况下,我给你留下了一个最适合我的解决方案。特别是如果一个人知道[的大小?数组的一维。对于字符数组非常有用,例如,如果我们需要一个大小不同的字符数组[20]。

int  size = 1492;
char (*array)[20];

array = new char[size][20];
...
strcpy(array[5], "hola!");
...
delete [] array;

键是数组声明中的括号。

其他回答

在c++ 11中可以:

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

这样,内存就不会被初始化。要初始化它,可以这样做:

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

示例程序(用"g++ -std=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]

我在创建动态数组时使用这个。如果你有一个类或结构。这是可行的。例子:

struct Sprite {
    int x;
};

int main () {
   int num = 50;
   Sprite **spritearray;//a pointer to a pointer to an object from the Sprite class
   spritearray = new Sprite *[num];
   for (int n = 0; n < num; n++) {
       spritearray[n] = new Sprite;
       spritearray->x = n * 3;
  }

   //delete from random position
    for (int n = 0; n < num; n++) {
        if (spritearray[n]->x < 0) {
      delete spritearray[n];
      spritearray[n] = NULL;
        }
    }

   //delete the array
    for (int n = 0; n < num; n++) {
      if (spritearray[n] != NULL){
         delete spritearray[n];
         spritearray[n] = NULL;
      }
    }
    delete []spritearray;
    spritearray = NULL;

   return 0;
  } 

如果行长是编译时常数,c++ 11允许

auto arr2d = new int [nrows][CONSTANT];

请看这个答案。像gcc这样的编译器允许将变长数组作为c++的扩展,可以使用如下所示的new来获得完全的运行时可变数组维度功能,就像C99所允许的那样,但是可移植的ISO c++仅限于第一个维度是变量。

另一个有效的选择是手动对一个大的1d数组进行2d索引,正如另一个答案所示,允许与真正的2d数组相同的编译器优化(例如,证明或检查数组不会彼此别名/重叠)。


否则,您可以使用指向数组的指针数组来支持类似连续2D数组的2D语法,尽管这不是一个有效的单一大分配。你可以使用循环初始化它,就像这样:

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

上面,对于colCount= 5和rowCount = 4,将产生以下结果:

在删除指针数组之前,不要忘记使用循环单独删除每一行。另一个答案中的例子。

我建议使用2D向量而不是2D数组。基本上尽可能使用向量主要是因为

动态内存分配没有麻烦 自动内存管理

下面是一个小代码片段,您可以在其中创建一个动态大小的数组

vector<vector<int>> arr;
for (int i=0; i<n; i++)
{    
    vector<int> temp;
    for (int j=0; j<k; j++)
    {
        int val;
        //assign values
        temp.push_back(val);
    }
    arr.push_back(temp);
}

这是一个老答案,但我喜欢在c++中这样定义动态数组

int sizeY,sizeX = 10;
 //declaring dynamic 2d array:
    int **ary = new int*[sizeY];
    for (int i = 0; i < sizeY; i++) 
    {
     ary[i] = new int[sizeX];
   }

您可以像这样在运行时更改大小。 这是在c++ 98中测试的