为多维数组创建内存空间

时间:2017-05-16 14:14:04

标签: c++ multidimensional-array new-operator dynamic-memory-allocation

我正在学习c ++并在书中找到了这个

array_ptr = new int[3][5][4];

这用于使用new将内存分配给多维数组。它还说明第一维可以是一个变量,其值在运行时提供,其他变量必须是常量。 我试着运行这段代码

int *p = new int[3][5][6];

但它显示错误。 有人可以详细说明。

3 个答案:

答案 0 :(得分:2)

这是你想要的:

int (*p)[5][6] = new int[3][5][6];

从C ++ 11开始,您可以要求编译器为您解释p的类型:

auto p = new int[3][5][6];

你不需要任何特殊的东西来删除这样的数组:

delete [] p;

选择类型背后的逻辑很简单:

在此行中:int *p = new int[10]您正在创建array of 10 ints并使用pointer to int来存储地址。

一般情况下,如果您要分配array of N Ts(其中N是大小且T是类型),则使用pointer to T存储地址。

同样的规则可以应用于多维数组,因为它们实际上是嵌套的1D数组。

当您尝试分配多维数组:p = new int[4][5][6]时,您正在创建array of 4 arrays of 5 arrays of 6 ints。因此,您需要pointer to array of 5 arrays of 6 ints,即int (*p)[5][6]

换句话说,int [3][4][5]可以被视为大小为3的一维数组。它由int [4][5]类型的其他数组组成。这些数组中的每一个都具有4的大小,并且由int [5]类型的其他数组组成,而这些数组又包含5 int s。

P.S。其他答案的作者似乎赞成使用int ***并分别为每个嵌套数组分配内存。这样做可能看起来很聪明,但实际上它更慢且更危险(如果你弄乱你的内存管理)。该技巧的唯一优势是它提供了我们习惯使用的方便界面(p[z][y][x])。

但是有一个更好的解决方案:int *p = new int[x_sz * y_sz * z_sz];。您需要将3D索引转换为1D索引(p[x + x_sz * (y + z * y_sz)]而不是p[z][y][x])才能使其正常工作,但在我看来它更方便(并且肯定更快)。

当然,在实际代码中,您应该使用std::vector来存储这样的数组编写自己的包装类,这将自动计算索引。

答案 1 :(得分:-1)

3d数组与指向int的指针不同,你不能使它们相同。

如果需要动态分配,可以使用特殊类std::vector(最佳选择),std::array或编写下一个代码:

int ***p = new int**[3];
for (int i = 0; i < 3; ++i) {
  p[i] = new int*[5];
  for (int j = 0; j < 5; ++j) {
    p[i][j] = new int[6];
  }
}

答案 2 :(得分:-1)

为了创建动态3d数组,你必须使用指向指针的指针)

const int xSize = 3;
const int ySize = 5;
const int zSize = 4;

int*** p = nullptr;

// creating array of pointers to pointers
p = new int** [xSize]

// for each pointer to pointers, create array of pointers
for( int i = 0; i < xSize; ++i )
  p[ i ] = new int* [ySize];

// now we have 2d array of pointers, for each of them allocate array
for( int i = 0; i < xSize; ++i )
  for( int j = 0; j < ySize; ++j )
    p[ i ][ j ] = new int [zSize];

但是使用矢量要好得多

vector<vector<vector<int> > > v3d;

v3d.resize( 3 );

for( int i = 0; i < xSize; ++i )
  v3d[ i ].resize( ySize );

for( int i = 0; i < xSize; ++i )
  for( int j = 0; j < ySize; ++j )
    v3d[ i ][ j ].resize( zSize );