我必须在 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();
错误地j
值height
;没有意识到,你修改了gu2d[i+1][0]
。如果gu2d
是向量的向量,则gu2d.at(i).at(j)
您将获得绑定检查和一个很好的例外。
- 为什么网格被定义为指向长度=宽度数组的指针,并且迭代发生在索引上,直到宽度,按高度移动地址?
您可以将 2D 矩阵视为由 width
行单元格组成的数组,其中每行由 height
个单元格组成。
所以第一个指针(newGrid
(的长度width
因为它引用width
行。
每行都有长度height
,因此newGrid
引用的width
值由 height
的空格分隔(移动((在指针度量中(。
我想如果你阅读这个问题的第一个答案,你会更清楚
如何使用 new 在 C++ 中声明 2d 数组?
- 然后我是否应该声明一个长度=宽度的数组,并带有指向长度=高度*深度数组的指针,这将导致以下代码
我不是英语母语人士,但在我看来,你选择了不愉快的名字顺序。我想你应该在width
之前使用depth
.
但是,使用您的真实姓名(width
是第一个索引的维度,第二个索引的height
,第三个索引的depth
(......
完全。
您的代码应该更改
newGrid = new int**[height*depth];
宽度
newGrid = new int**[width];
在 3D 情况下,您可以看到newGrid
(使用您选择的一个名称(一个 2D 矩阵数组width
其中 2D 矩阵是 height
行depth
单元格的数组。所以每个 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;
不好意思。