Better for complex data members to be dynamically or statically allocated?

114 views Asked by At

I am considering a problem and can't come to a conclusive "better" of the two options. It comes down to deciding whether a complex data member (ie, not a primitive) should be a pointer or simply a value. (Note, I have seen many questions about pointer vs reference for data members, but nothing regarding pointer vs value) The biggest things I'm weighing are

  1. Lifespan of the data member (whether it lives the full life of it's owner).
  2. In the case when it does last the full lifespan, reducing memory fragmentation.

Consider the following code:

class PlayerStatistic
{
    int m_MaxValue;
    int m_CurrentValue;
    // And many other things that round out a player statistic
}

class PlayerStatisticManager
{
    //While in this case, it may be better to store stats as a list of some kind and
    //identify them by a StatId or something, for this example, I'm declaring them 
    //individually.
    PlayerStatistic* m_pHealth;
    //OR
    PlayerStatistic m_Health;

    // And many more statistics.
}

In the above example, every player always has health. Their health statistic is ALWAYS the lifespan of the StatisticManager, which in turn is ALWAYS the lifespan of the player.

If this weren't the case, I would prefer the pointer, so that NULL can be indicative that the object doesn't exist (which might be better for a stat that not all players have).

However, because that's not the case, I think I would rather have it stored as value, in order to make fewer larger memory allocations, rather than many small memory allocations.

Is my thinking sound, or is there something I'm not considering?

Edit - My choice of words ("pointer vs value") was poor. What I meant was what one of the answers clarified:

What you are referring to here is weather it's better to have the mHealth statically or dynamically allocated;

Moreover, in this case, I know that health's lifespan is the player's lifespan, so my question basically comes down to memory. Is it better memory management to statically allocate data members in the interest of having fewer allocations, and instead doing one big allocation (when Player get newed).

3

There are 3 answers

1
Pandrei On

I think you got things a little miked up: "by reference" or "by value" refers to how you pass parameters to a function. By pointer, or by value is preferred because in that case only the pointer to a memory location is passed; for structures for example, all the members are copied to the stack - adding overhead.

What you are referring to here is weather it's better to have the mHealth statically or dynamically allocated; and that is a design question and depends on the application. Both ways are fine - but there is no ultimate better solution - it depends....

2
Xephon On

One thing you need to consider is how you are going to use the data. Whether you need it to be changed through various routines or simple monitor it in most processes.

If you indeed need to change it and expose the change to other routines, better pass it by reference in which case pointer would be a better solution.

On the other hand, if it is a simple value to be monitored and not changed often, I would suggest pass by value especially monitoring does not happen frequently.

In your case, the following is my analysis: 1. Player health may change frequently in case of event like a battle. The data is better passed by reference in this case. 2. Player health is monitored by a few processes infrequently when not in battle, like when the user is querying the health value. In this case, data is better passed by value so accidental change to the value would not affect the object instance itself.

Personally, I would use pointer in PlayerStaticManager. This gives the option of passing the value or reference in different scenarios. If you need to pass by reference, pass the pointer along. If you need to pass by value, make a copy of the content, pass it along and forget about the copy.

Hope this helps.

2
aeagal On

Only use a pointer if the lifetime of the member will be different from the lifetime of the containing object.