I’ve got a game that has a grid, which is a 2D array. This array is filled with a struct of information.
struct GridCell
{
uint mCellID;
Vector2 mPosition;
uint mLevel;
int mCellType;
};
class Grid
{
public:
Grid();
~Grid()
protected:
// Heap
GridCell[][] mGridCells;
// Dynamic
GridCell*[][] mGridCells;
};
Keeping in mind that there can be many Grids in memory at once, and that those gridcell can range from very small to very large:
Is this better suited to be a heap of gridcells or dynamic (pointer) gridcells?
From what I understand:
Heap cells will take up a large chunk of memory
Dynamic cells still will, but it will be of pointers, not the entire struct. However, this could lead to fragmented memory?
I’m not sure of which one is the best for this scenario, and I probably don’t fully understand the differences between the two either. Help?
Types in C++ have a fixed size. It’s not true that your
GridCells will range from very small to very large. They’ll be one or the other.sizeof(GridCell)is fixed. They might each point to objects of different sizes, but those objects are not part of the size of theGridCell.Either way, both methods you propose will have exactly the same amount of
GridCells in memory, so you save nothing by using pointers. In fact, the dynamically allocated approach will use more memory because you’re also storing pointers to each cell. The only way the pointer approach could be more memory efficient is if you used singleGridCellobjects to represent more than one cell in theGrid. That is, some of the pointers would be the same.What this really comes down to is which one is more manageable and the answer is always “the method without the pointers”. It means your
Gridobjects will automatically manage the construction and destruction of theGridCells without you having to care about it, helping you avoid memory leaks. If you use the pointer method, you will have to loop through your arrays in the constructor ofGrid, doingnew GridCell()for each element. You’ll also need to do the same in the destructor, doingdeleteon each cell you dynamically allocated. This is a pain, especially when it’s unnecessary.In the cases where pointers are required, smart pointers are much more preferable.
Furthermore, you may even be better off using a
std::array<std::array<GridCell, N> M>for your fixed sized arrays. It encapsulates the array for you, allowing you to use it as you would any other Container from the standard library.