Skip to main content
gamedev.net
🔒 Locked 🎲 GameMaker

create/delete objects

Started by warcod3 Aug 11, 2013 at 1:21 PM 8 replies 2.8k views
Original Post
warcod3
warcod3

In the last few days I tried to understand some basic concepts in making games, and I'm stuck at the object oriented part. I made a few games in a program named game maker in the last years, and I was trying to implement a similar mechanism in c++.

I don't know much c++, maybe the basics. I created a simple ~simulation, where little cells reproduce and die. My problem is, that I create objects, but can't properly delete them. And that results in eating up the memory. If anyone could help me understand what am I doing wrong, I would be grateful. Here's the code:

The creation code:


blbob *tmp;
tmp = new blbob;
tmp->x = x;
tmp->y = y;
blbob_numb++;

in the while loop:


it=obj_list.begin();
while(it!=obj_list.end())  {
    if((*it)->z==1)  {
        (*it)->step();
	it++;
    }else  {
        it = obj_list.erase(it);
    }
}

And if I try to delete it using "delete", i get an error in vc++ and nothing in codeblocks.

in the destructor:


~blbob()  {
        it = obj_list.erase(it);
}

in the while loop


while(it!=obj_list.end())  {
    if((*it)->z==1)  {
        (*it)->step();
	it++;
    }else  {
        delete *it;
    }
}
Madhed
Madhed

You need to delete AND erase from your list. Otherwise you will access invalid memory the next time the loop is executed.

warcod3
warcod3

But I'm erasing it in the destructor. And tried erasing it before and after the 'delete' too. I always get the same error.

SyncViews
SyncViews

What is it? What is obj_list?

Personally I would advise unique_ptr, or possibly shared_ptr+weak_ptr to make objects that reference other objects easier (e.g. "std::weak_ptr target").

That way you don't have to track down every place things might be removed from the list, the list itself can delete them as needed.


class ObjectTracker
{
public:
    typedef std::vector<std::unique_ptr<BaseObject> > Objects;
    
    //no need for an ~ObjectTracker(), the vector will do the right thing
    
    void step()
    {
        //Not sure what the z is in your code, but assuming some sort of alive/die flag
        for (size_t i = 0; i < objects.size(); ++i)
        {
            bool alive = objects[i]->isAlive();
            if (alive)
                objects[i]->step();
            alive = objects[i]->isAlive();
            if (alive)
            {
                ++i; //next object
            }
            else
            {
                //erase, delete and next
                objects.erase(objects.begin() + i);
            }
        }
    }
    
    //Safe even when called from a BaseObject::step because the loop
    //above has no iterators, so the only effect this has in
    //increasing the return value of size().
    //New objects will have their step method called on the step they
    //are added.
    //Another alternative is to have a newObjects list, and copy its
    //contents to objects after the step loop.
    void addObject(std::unique_ptr<Object> &&object)
    {
        objects.push_back(std::move(object));
    }
private:
    Objects objects;
};


EDIT:

redesigned it slightly and provided a way to add objects safely even from within step.

stitchs_login
stitchs_login

Does a blbob get put into the list of objects? If this is the case, then the destructor doesn't need to erase from the list, as the portion that iterates through this is responsible for it.

You need to delete AND erase from your list. Otherwise you will access invalid memory the next time the loop is executed.

Like Madhed said, you need to do both at the point of erasing from the list. The destructor should be used to clean-up resources that the object requires and creates (an image, sound etc.), it shouldn't handle erasing itself from a container, as it shouldn't know whether or not it is in a container. It only cares that it is itself and frees up resources correctly, when it goes out of scope/a call to delete is made.

Stitchs.

warcod3
warcod3

Sorry. obj_list is a list. Thanks, I will try your method with a vector.

But am I missing something, because I don't see where you delete the object. Is enough the erase in case of a vector? ->that's what the unique_ptr does?

And thanks for the destructor part Stitchs.

weeska
weeska

But am I missing something, because I don't see where you delete the object.

I'm not sure if i got you right. With unique_ptr, you don't need to delete the object, it takes care of that itself.

warcod3
warcod3

Thank you all! :) It's working now.

warcod3
warcod3

Thanks. I will look into it.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.