CPP 3D 动态创建由单个内存块组成的 3D 数组



我必须在 3D 上实现由 1 和减 1 表示的 3D 伊辛晶格的模拟,如果可以在运行时确定大小(以获得更大的灵活性(,那将非常有用。由于对条目的访问很多,因此内存分配应尽可能本地。如果找到 2D 数组的内容:使用内存复制 2D 数组?:

GridUnit** newGrid;
newGrid = new GridUnit*[width];
newGrid[0] = new GridUnit[width * height];
for (int i = 1; i < width; i++)
    newGrid[i] = newGrid[i-1] + height;

解除分配变得更加简单:

delete[] newGrid[0];
delete[] newGrid;

而且我的评分太低,无法评论或回复帖子。关于代码,我基本上有两个问题:1.为什么网格被定义为指向数组的指针 length = width迭代发生在一个索引上升到宽度上,按高度移动地址?这不是弄乱了行和列索引吗?2.然后我是否应该声明一个带有指向length=height*depth数组的指针的length=width数组,这将导致以下代码:

int*** new3dGrid(int width, int height, int depth){
  int*** newGrid;
  newGrid = new int**[height*depth];
  newGrid[0][0] = new int[width * height * depth];
  for (int i = 1; i < width; i++){
    newGrid[i] = newGrid[i-1] + height*depth;
    for (int j=1;j<height;j++){
      newGrid[i][j]=newGrid[i][j-1]+depth;
    }
  }
  return newGrid;
}

首先:我强烈建议您在可能的情况下使用标准C++容器; 在2D情况下(注意:未测试(

std::vector<std::vector<GridUnit> >  gu2d (width, std::vector<GridUnit>(height));

我强烈建议这样做,特别是如果您提到的示例不是绝对清楚的话。

考虑您是否在位置 i 访问,j

gu2d[i][j] = GridUnit();

错误地jheight;没有意识到,你修改了gu2d[i+1][0]。如果gu2d是向量的向量,则gu2d.at(i).at(j)您将获得绑定检查和一个很好的例外。

  1. 为什么网格被定义为指向长度=宽度数组的指针,并且迭代发生在索引上,直到宽度,按高度移动地址?

您可以将 2D 矩阵视为由 width 行单元格组成的数组,其中每行由 height 个单元格组成。

所以第一个指针(newGrid(的长度width因为它引用width行。

每行都有长度height,因此newGrid引用的width值由 height 的空格分隔(移动((在指针度量中(。

我想如果你阅读这个问题的第一个答案,你会更清楚

如何使用 new 在 C++ 中声明 2d 数组?

  1. 然后我是否应该声明一个长度=宽度的数组,并带有指向长度=高度*深度数组的指针,这将导致以下代码

我不是英语母语人士,但在我看来,你选择了不愉快的名字顺序。我想你应该width之前使用depth.

但是,使用您的真实姓名(width是第一个索引的维度,第二个索引的height,第三个索引的depth(......

完全。

您的代码应该更改

newGrid = new int**[height*depth];

宽度

newGrid = new int**[width];

在 3D 情况下,您可以看到newGrid(使用您选择的一个名称(一个 2D 矩阵数组width其中 2D 矩阵是 heightdepth单元格的数组。所以每个 2D 矩阵的大小都是 heigth * depth .

注意:请记住删除

delete newGrid[0][0];
delete newGrid;

PS:对不起,我的英语不好

---编辑---

抱歉:我还没有看到关于你的new3dGrid假设的重要一点:你应该分配三个指针,而不是两个:newGrid,如int***,用于大小width; newGrid[0],作为width * height大小的int**; newGrid[0][0],如int*,大小width * height * depth。这三种类型的指针需要不同的分配区域。

我建议使用不同的模板版本(注意:未经测试([由本·福格特更正;谢谢!

template <typename T>
T*** new3dGrid (unsigned height, unsigned width, unsigned depth)
 {
   T*** newGrid;
   newGrid       = new T**[width];
   newGrid[0]    = new T*[width * height];
   newGrid[0][0] = new T[width * height * depth];
   for ( unsigned i = 0U ; i < width ; ++i )
    {
      if ( i > 0U )
       {
         newGrid[i]    = newGrid[i-1U]    + height;
         newGrid[i][0] = newGrid[i-1U][0] + height * depth;
       }
      for ( unsigned j = 1U ; i < height ; ++j )
         newGrid[i][j] = newGrid[i][j-1U] + depth;
    }
   return newGrid;
 }

你应该删除三个指针

delete newGrid[0][0];
delete newGrid[0];
delete newGrid;

不好意思。

最新更新