指针或堆对象的2D数组

时间:2012-12-19 23:14:10

标签: c++ arrays memory-management

我有一个有网格的游戏,这是一个2D数组。这个数组充满了信息结构。

struct GridCell
{
    uint mCellID;
    Vector2 mPosition;
    uint mLevel;
    int mCellType;
};

class Grid
{
public:
    Grid();
    ~Grid()

protected:
    // Heap
    GridCell[][] mGridCells;

    // Dynamic
    GridCell*[][] mGridCells;
};

请记住,内存中可能同时存在多个网格,并且这些网格单元的范围可以从非常小到非常大: 这更适合成为一堆gridcells或动态(指针)gridcells吗?

据我所知: 堆细胞将占用大量内存 动态单元格仍然会,但它将是指针,而不是整个结构。但是,这可能导致内存碎片?

我不确定哪种方案最适合这种情况,我可能也不完全理解两者之间的差异。救命?

2 个答案:

答案 0 :(得分:3)

C ++中的类型具有固定大小。你GridCell的范围从非常小到非常大都是不正确的。他们将是一个或另一个。 sizeof(GridCell)已修复。它们可能都指向不同大小的对象,但这些对象不是GridCell大小的一部分。

无论哪种方式,你提出的两种方法在内存中都会有相同数量的GridCell,所以你不需要使用指针来保存任何内容。事实上,动态分配的方法将使用更多内存,因为您还存储指向每个单元格的指针。如果您使用单个GridCell对象来表示Grid中的多个单元格,则指针逼近可以提高内存效率的唯一方法。也就是说,一些指针是相同的。

这真正归结为哪一个更易于管理,答案总是“没有指针的方法”。这意味着您的Grid对象将自动管理GridCell的构造和销毁,而无需您关心它,从而帮助您避免内存泄漏。如果使用指针方法,则必须在Grid的构造函数中遍历数组,为每个元素执行new GridCell()。您还需要在析构函数中执行相同操作,在动态分配的每个单元格上执行delete。这是一种痛苦,特别是在不必要时。

在指针需要的情况下,智能指针更为可取。

此外,对于固定大小的数组,使用std::array<std::array<GridCell, N> M>甚至可能会更好。它为您封装了数组,允许您像使用标准库中的任何其他容器一样使用它。

答案 1 :(得分:2)

最好不使用它并使用std :: vector。使您的2d数组1d并将值直接存储到向量中。或者,如果你真的必须有2维,你可以创建一个向量矢量。