SFML community forums

Help => General => Topic started by: S_BISHOP on December 29, 2018, 04:27:32 pm

Title: How does one manage the life time of a pointer ? explicitly calling delete
Post by: S_BISHOP on December 29, 2018, 04:27:32 pm

I have a Player type and he has a function to fire his Weapon type, that creates a Projectile type, pushing each new Projectile type pointer back into a vector of the same type with each shot fired.

all works beautifully. Apart from when its time to clear that memory, i pass the vector of pointers to this
function template, but its never safe and always results in a program crash ?

How do you keep tabs on a pointer that is passed around many many function of global program scope, and when do you know for sure it is completely untouched un-accessed so it can be safely deleted ?


this is my current methodology with in my simple game engine, is this typically how memory maement is done in game programming ?

thanks.




freeMemVecPerishTarget(t.firedProjectilesPtrs);


template<typename T>
inline void freeMemVecPerishTarget(vector<T*>& t){
   for (auto it = t.begin(); it != t.end();) {
      //
      (*it)->perishTotal = ((*it)->perishTotal < (*it)->perishTarget) ? (*it)->perishTotal += (*it)->perishUpdate : (*it)->alive = F;
      //
      if(!(*it)->alive) {
         delete *it;
         it = t.erase(it);
      } else
         ++it;
   }
}

 

Title: Re: How does one manage the life time of a pointer ? explicitly calling delete
Post by: Hapax on December 30, 2018, 11:40:26 am
It should be clarified  that the lifetime of a pointer is limited to its scope. The data that it points to, however, is manually created and destroyed at arbritary times.

I'm not sure what you mean by passing a vector of pointers is unsafe. As long as those pointers are pointing to the same thing, there seems to be no reason that they don't act as if you are using the original pointers. Effectively, if the pointers themselves aren't getting modified, there should be no difference between passing the vector by value or reference (so use reference, as you are doing). Of course, this means that those pointers and their data will be missing if they are still used outside of this function. Also, remember that the pointers' indices will have changed if and have been deleted. On top of that, any pointers to the elements of the vector (pointer to a pointer) will now be invalid.

You should definitely look into using smart pointers, assuming you are using C++11 or later.
For example, each "unique pointer" (std::unique_ptr) is used to hold the data and it "attached" to that pointer. You can still pass around the pointer but it's always clear where the data is controlled due to stricter rules of passing around.
Also, using these "smart" pointers, the data itself gets destroyed and cleared when the pointer is destroyed - when it goes out of scope so there should be no surprises and no "non-deleted data without pointers".

NOTE: remember to post code within [code=cpp] [/code] tags
Title: Re: How does one manage the life time of a pointer ? explicitly calling delete
Post by: eXpl0it3r on December 30, 2018, 02:18:21 pm
Sounds like your game code could use some better code design. If you're passing around raw pointers as "owning" pointers to various places, you're setting yourself up for trouble.

Instead, you should make clear restrictions on what class owns objects and what classes only operate on these objects. Then you also don't need to pass by pointer, but you can pass by reference.
And finally, as Hapax already mentioned, once you have a clear ownership model, you can most of the time either store the objects directly on the stack, directly in a std::vector or if it needs to be allocated dynamically, you can use a unique_ptr for unique ownership and shared_ptr for shared ownership (which is most of the time not needed).
Title: Re: How does one manage the life time of a pointer ? explicitly calling delete
Post by: Raynobrak on January 05, 2019, 05:47:57 pm

How do you keep tabs on a pointer that is passed around many many function of global program scope, and when do you know for sure it is completely untouched un-accessed so it can be safely deleted ?


Have you heard about smart pointers ?  :)
https://fr.cppreference.com/w/cpp/memory/unique_ptr (https://fr.cppreference.com/w/cpp/memory/unique_ptr)
https://fr.cppreference.com/w/cpp/memory/shared_ptr (https://fr.cppreference.com/w/cpp/memory/shared_ptr)

Store shared pointers instead of "naked" pointers. shared_ptr uses a naked pointer internally, and frees the memory automatically when nobody points to it anymore.

In other words, no more "delete" or "new"  :D

EDIT : Just realised that's exactly what eXpl0it3r and Hapax said, sorry !