简体   繁体   中英

C++ - Freeing memory allocated in main but pointed to in a seperate class

I was wondering, if I create an object in main using the new keyword, then set that object (pointer) to be pointed to by a member of another class, setting the original pointer to null, where would I delete the allocated memory? I could do it in the second class's destructor but what if that object wasn't dynamically allocated?

Some code as an example:

World world;
Player* newPlayer = new Player("Ted");
world.setPlayer(newPlayer);
newPlayer = 0;

So now the 'player' member variable in World is pointing to the memory allocated by newPlayer and newPlayer is pointing to null. How should I deallocate this memory when I'm done with the World object?

This kind of complexity is why you should try to avoid raw pointers in C++. Smart pointers exist to solve this kind of problem, and save you the headache of manually tracking who has ownership of an object and when to delete it.

For example:

typedef boost::shared_ptr<Player> sp_Player;

struct World {
    sp_Player player;
    World(sp_Player p) : player(p) {}
};


sp_Player newPlayer = new Player("Ted");

World world;
world.setPlayer(newPlayer);

// Object is now automatically deleted at the correct time!

As noted in other answers it is easier to use smart pointers however in this case you can put the delete elsewhere.

If all players are passed to a World then World can deal with the memory - every time a World is destructed or when a different player is set the the Player that World holds has to be deleted. Also no Player should be destroyed anywhere else or otherwise it could be destroyed twice. However in this case I would make all Players be constructed by a method in World to keep it clear who owns the memory management and keep the same class creating and destroying the Player objects

Some very incomplete code is (note how the smart pointer code is much less and I think covers all cases - this does not)

class World
{
   Player *p;
 ...
}

World() : p(nullptr) {
  ...
}

~World() {
    delete p;
}

void World setPlayer( Palyer *aP ) {
    if ( p != aP) {
         delete p;
    }
    p = aP;
    ....
}

Player* World::createPlayer(std::string const& name){ 
  return new Player(name); 
} 

Note = Player(name) creates a Playeobject on the stack and that is not managed in your code by new and delete - and might be the best solution here.

Also need to deal with operator= and the copy constructor (for the latter best to stop it ever being called or it will need to duplicate the Player object so deleting the Original World and the copy will not both attempt to delete the same Player)

There is no absolute answer. The question is: why are you allocating the object dynamically to begin with? Once you've answered this, it's usually obvious where it should be deleted.

From the names of your objects, for example, I'd guess that world owns everything; that it decides the lifetime of players, etc. In which case, it should be responsible for the delete . As for the possibiltiy of allocating a Person on the stack: don't do that. Given that Person probably has a definitely lifetime which doesn't correspond to a block in a function (otherwise, why allocate it dynamically to begin with), it doesn't make sense to declare local variables of that type.

You just need to call delete when you are finished. To avoid the need for this though look into making use of shared pointers as they will relieve you of the need to do this.

Edit: To answer your comment, where you call delete depends on your application but ensure that you

  1. Dont delete it before you have allocated it.
  2. Dont delete it until you are sure nothing else needs to access it.

A possible place would be in the destructor of your World object, but it is impossible to say without knowing details of the rest of your application. This is why boost::shared_ptr is preferable.

new should always followed by delete. If you set the pointer to point to some other object without freeing up the memory it will result in dangling pointer

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM