动态分配2D int数组

时间:2011-12-20 00:51:55

标签: c++ arrays

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

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行):

  • 错误:new-declarator中的表达式必须具有整数或枚举类型|
  • 错误:'b'不能出现在常量表达式|

解决方案:

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

4 个答案:

答案 0 :(得分:2)

您无法传递指针来初始化数组的大小。其他人现在提到了这一点。

这篇文章(不是我的)似乎可以帮到你:http://eli.thegreenplace.net/2003/07/23/allocating-multi-dimensional-arrays-in-c/

你还应该考虑在Layer的构造函数中进行分配,然后删除它的析构函数中的内存(即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;
}

答案 1 :(得分:1)

  

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

很多。你正在分配两个单独的数组(一个“行数组”和一个“列数组”,而不是你需要的),然后你尝试做一些奇怪的事情。


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

int width=5;

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

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

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

这样你基本上将一维数组解释为二维数组(性能等于静态二维数组)。

为方便起见,最好用类包装索引; boost::multi_array也已为您完成此任务。

答案 2 :(得分:1)

首先,你的变量“a”和“b”是指针。你的代码: layer-&gt; tileGids = new int [a] [b] 是问题的根本原因。

我想在这里猜测你的意图,我认为你要做的是让layer.tileGids成为一个二维数组来引用一个大小的“网格”(mapSize.Width,mapSize.height)让你可以使用layer.tileGids [x] [y]。

来引用网格中的每个“单元格”

如果您确实尝试创建二维数组,则有两种方法可以执行此操作。

方法1:

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

请注意,对于使用向量的第二种方法,您不必按照第一种方法的要求进行任何内存清理,因为向量会自动处理它。但是,因为矢量可以动态增长,即你可以向它添加项目,你会失去固定大小数组的安全性,即如果你使用矢量方法,有人可能会意外地增加网格的大小,但如果他试图这样做的话你使用上面的第一种方法对它进行初始化会发生错误,你会立即知道出了什么问题。

答案 3 :(得分:0)

a和b在这里int*

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

也许你想说这个?

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