动态分配 2D 整数数组

Dynamically allocating 2D int array

本文关键字:数组 整数 2D 动态分配      更新时间:2023-10-16

有人可以指出我在以下代码中做错了什么吗?

int* a = NULL;   
int* b = NULL;   
a = new int[map->mapSize.width];
b = new int[map->mapSize.height];
layer->tileGids = new int[a][b];

以下是代码使用的:

typedef struct _size {
    int width, height;
} size;
class Map {
    size mapSize;
}
class Layer {
    int * tileGids;
}

编辑:编译器错误(在第一段代码的第6行(:

  • 错误:新声明符中的表达式必须具有整型或枚举类型|
  • 错误:"b"不能出现在常量表达式中|

溶液:

我决定接受光之炼金术士的回答。从本质上讲,对我有用的是使用向量而不是数组。Vector为您管理内存,因此更容易处理。

不能传递用于初始化数组大小的指针。其他人现在提到了这一点。

这篇文章(不是我的(似乎可能会对你有所帮助:http://eli.thegreenplace.net/2003/07/23/allocating-multi-dimensional-arrays-in-c/

您还应该考虑在类层的构造函数中进行分配,然后删除其析构函数中的内存(即 RAII - 资源获取是初始化(。这被认为是好的风格。

最后,您可以考虑使用连续内存和自定义索引方案,您可以轻松地使用 Layer 进行封装。这当然取决于事情会变得多大。它们越大,连续记忆的情况就越好。

这应该给你一个味道。

#include <iostream>
#include <cstdlib>
int main()
{
   const size_t ROWS = 5; 
   const size_t COLS = 2; 
   const size_t size = ROWS*COLS;
   int* arr = new int[size];
   int i = 0;
   for ( size_t r = 0 ; r < ROWS; ++r )
   {
      for (size_t c = 0; c < COLS; ++c )
      {
         arr[r*COLS+c] = i++;
      }
   }
   for ( int j = 0; j < i; ++j)
   {
      std::cout << arr[j] << std::endl;
   }
   delete [] arr;
}

首先,你的变量"a"和"b"是指针。您的代码:layer->tileGids = new int[a][b]是问题的根本原因。

我试图猜测你的意图,我认为你想做的是使layer.tileGids成为一个二维数组来引用大小的"网格"(mapSize.Width,mapSize.height(,以便你可以使用layer.tileGids[x][y]引用网格中的每个"单元格"。

如果您确实尝试创建二维数组,则有两种方法可以做到这一点。

方法一:

class Layer {
int ** tileGids; // NOTE the "**" to indicate tileGids is a pointer to pointer i.e. 2D array.
}

要初始化它:

int width = map->mapSize.width;
int height = map->mapSize.height;
layer.tileGids = new int*[width]; // NOTE the "int*" to indicate tileGids is a new array of pointers to int.
for (int i = 0; i < width; i++) // Initialize each element in layer.tileGids[] to be a pointer to int.
{
  layer.tileGids[i] = new int[height];
}

现在,您可以使用以下命令访问 layer.tileGids 中的项目:

int value = layer.tileGids[x][y] // where 0 <= x < width and 0 <= y < height

要解除分配此数据结构,类似于分配它的方式,您需要在每个"行"中释放每个动态分配的数组:

for (int i = 0; i < width; i++)
    {
      delete [] layer.tileGids[i]; // Deallocate each row.
    }
delete [] layer.tileGids; // Deallocate "array" to the pointers itself.

方法2:

现在,另一种更简单、不那么混乱的方法(避免指针(是使用 C++ 向量类。您需要进行以下更改:

#include <vector>
class Layer {
  vector<vector<int> > tileGids; // Note the space at "<int> >".
}

要初始化:

int width = map->mapSize.width;
int height = map->mapSize.height;
layer.tileGids = vector<vector<int> >(width, vector<int>(height, 0));  // Initialize all entries to 0.

要访问元素:

int value = layer.tileGids[x][y]; // Where 0 <= x < width and 0 <= y < height

请注意,对于使用向量的第二种方法,您不必像第一种方法那样执行任何内存清理,因为向量会自动处理它。 但是,由于向量可以动态增长,即您可以向其添加项目,因此您将失去拥有固定大小数组的安全性,即如果您使用 vector 方法,有人可能会意外增加网格的大小,但如果他尝试这样做当您使用上面的第一种方法初始化它时,会发生错误,您将立即知道出了问题。

有人可以指出我在以下代码中做错了什么吗?

好多。您正在分配两个单个数组("行数组"和"列数组",而不是您需要的(,然后您尝试做一些奇怪的事情。


通常,您不能(严格来说(在C++中动态分配 2D 数组(因为类型系统仍然需要在编译时知道类型以及维度(。你可以用一个数组左右的数组来模拟它,但最好的方法是分配一个 1D 数组:

int width=5;
std::vector<int> tab(width*height);

然后通过手动计算坐标来访问元素:

// access the element (1,2)
tab[1 + 2*width] = 10;

这样,您实际上是将一维数组解释为 2D 数组(性能等于静态二维数组(。

那么为了方便起见,最好用类包装索引; boost::multi_array也已经为您完成了这项工作。

这里int* a和b:

layer->tileGids = new int[a][b];

也许你的意思是这样说?

layer->tileGids = new int[*a][*b];