Mechanical_Lamb
Mechanical_Lamb

Reputation: 13

Heap memory allocation for pointers to object/objects in C++

I read a book about programming patterns in games, and decided I would give writing a small engine for fun/practice while I'm not taking classes, which makes a lot of use of object pointers.

I've created a Tile class to represent an area of the map (situated on a standard 2D coordinate plain, which is a 2D array of pointers to Tile objects) which has other types of objects (infamous tile traps, a character, and a ground type) as shown below, which holds pointers to the data the tile object will hold.

class Tile
{
public:
    enum TileType{
        WATER_DEEP,
        WATER_SHALLOW,
        GRASS,
        MUD
    };

    Trap* getTileTrap();
    GameObject* getTileObject();
    TileType* getTileType();

    Trap *tileTrap;
    GameObject *tileObject;
    TileType *tileType;

    Tile();
    virtual ~Tile();

protected:
private:
};

What I'm curious about is whether it is more efficient, memory/performance wise, to keep it how it is written, having this tile object (which is allocated on the heap) contain pointers to other objects, or should I scrap the pointers and simply return the objects?

If I keep it how it is written, are the objects the pointers point to created somewhere else on the heap? Will they be allocated somewhere random, or will they be allocated along with the space allotted to the Tile object when it is created?

Upvotes: 1

Views: 813

Answers (2)

riodoro1
riodoro1

Reputation: 1256

The pointer is useful when You want storage that does not expire with a function that creates it or can be "shared". You can think of them as sort of a global variable, it's accessible as long as You haven't forgotten the pointer or haven't freed the memory. You can for example have one Tile object create the GameObject and another object of Tile type share the pointer to the same GameObject. But a pointer is NOT an object, that means that in case of your Tile class you need to allocate all the members on the heap and then release them manually when appropriate.

For example I think there is no point to do TileType* getTileType(); because in the constructor you would have to call new and then in the destructor delete for a member tileType that takes almost no space and is not required to be shared.

You should familiarise yourself with what a pointer is and what it's useful for, it has its uses but also its limitations. Once You realise the potential that holding a pointer instead of a variable has You will be able to quickly judge which to use including the potential performance gain/penalty.

Upvotes: 0

Vittorio Romeo
Vittorio Romeo

Reputation: 93384

it is more efficient, memory/performance wise, to keep it how it is written, having this tile object (which is allocated on the heap) contain pointers to other objects, or should I scrap the pointers and simply return the objects?

It's almost never more efficient to use indirection and dynamic allocation. It is only more efficient when the object you're storing are expensive to copy (e.g. copy-on-write strings). It's also "required" when you want to refer to the same object without copying it.

tl;dr:

  • Prefer values unless you have a good reason to introduce indirection.
  • Prefer references to pointers as they don't have a "null state".

  • Consider TileType: it's an enum whose size is very likely to be less or equal than sizeof(void*). You gain nothing and lose everything by storing it as a pointer and returning it by pointer.

    If you store it via pointer, this means that you'll probably require dynamic allocation. Every time you access it you need to jump through a pointer.

  • Regarding Trap and GameObject: depending on their size and whether or not you want reference semantics you might want to use a std::unique_ptr or std::shared_ptr to store them, and return a Trap&/GameObject& to allow access.


If I keep it how it is written, are the objects the pointers point to created somewhere else on the heap? Will they be allocated somewhere random, or will they be allocated along with the space allotted to the Tile object when it is created?

It seems that you need to read a good C++ book and understand the basics of pointers and references. Unless you initialize your pointers, they will have garbage values.

  1. You shouldn't use raw pointers for ownership. You should use smart pointers.

  2. You shouldn't use dynamic allocation unless you have a good reason to do that.

Upvotes: 6

Related Questions