【问题标题】:Creating memory space for multi-dimensional array为多维数组创建内存空间
【发布时间】:2017-10-15 16:21:52
【问题描述】:

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

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

这用于使用 new 为多维数组分配内存。它还指出,虽然第一维可以是在运行时提供其值的变量,但其他维度必须是常量。 我试图运行这段代码

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

但它显示错误。 谁能详细说明一下。

【问题讨论】:

  • 扔掉那本书,换成something saner
  • 无论如何,不​​要将错误消息复制到您的问题中。人们实际上可能会告诉您错误消息意味着int*int (*)[5][6] 之间存在类型不匹配。
  • @FRob 你为什么这么沮丧,冷静点
  • 这是一个 C 答案,但就原始数组的工作方式而言,它也适用于 C++:Correctly allocating multi-dimensional arrays。请用它来打击所有喋喋不休的指针到指针到指针的人......
  • @HolyBlackCat 这本书显然教指针摆弄和手动内存管理,这是困难和不必要的。说明作者不了解相关编码实践或不在意。我可能有点草率,这本书实际上说明了为什么不马上做这样的事情,或者只是作为一个旁注,但很可能它是由一个认为 C++ 基本上是 C 的作者写的,基本上是 fortran。由于不幸的是,这很常见并且对后来的学习和能力造成很大损害,所以我觉得有必要提出替代方案。

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


【解决方案1】:

这是你想要的:

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 来存储地址。

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

当您尝试分配多维数组: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] 的数组组成,而这些数组又包含5ints。


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来存储这样的数组编写你自己的包装类,它会自动计算索引。

【讨论】:

  • 好回答 @HolyBlackCat 需要添加如何删除。
  • @Shadi 已编辑,以防对某人不明显。
【解决方案2】:

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];
  }
}

【讨论】:

  • 拜托,看在上帝的份上,请使用std::vector 处理这类事情 - 它所以更安全、更容易。
【解决方案3】:

为了创建动态 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 );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-09
    • 2011-08-19
    • 2013-04-21
    • 1970-01-01
    相关资源
    最近更新 更多