Page 1 of 1

GarbageCollector freezes

Posted: Mon Jul 30, 2012 2:45 pm
by YourNerdyJoe
I made a garbage collector for my game to make sure all of the entities get deleted at the end. Whenever you try to delete an entity it freezes. It has its own Alloc and Dealloc functions, and MarkTrash deletes that entity the next time Collect is called by adding it to the trash list.
GarbageCollector:

Code: Select all

template<class T>
struct Block
{
	T* ptr;
	unsigned long length;
};

template<class T>
class GarbageCollector
{
protected:
	LinkedList<Block<T>> mem;
	LinkedList<T*> trash;
public:
	GarbageCollector();
	~GarbageCollector();

	static inline GarbageCollector<T>& Inst() {
		static GarbageCollector<T> inst;
		return inst;
	}

	//memory management
	T* Alloc();
	T* Alloc(unsigned long length);
	bool Dealloc(T* ptr);
	T* Track(T* ptr,unsigned long length = 1);
	//garbage collection
	void MarkTrash(T* ptr);
	void Collect();
	//mem info
	unsigned long GetLength(T* ptr);
	//clean up remaining memory
	void CleanUp();
};
Collect function:

Code: Select all

template<class T>
void GarbageCollector<T>::Collect()
{
	Node<T*>* it;
	for(it=trash.first;it!=NULL;it=it->next)
	{
		Node<Block<T>>* bIt;
		for(bIt=mem.first;bIt!=NULL;bIt=bIt->next)
		{
			if(it->data == bIt->data.ptr)
			{
				unsigned long length = bIt->data.length;
				if(length>1){
					delete[] bIt->data.ptr;
				}
				else{
					delete bIt->data.ptr; //freezes here
				}

				mem.DeleteNode(bIt);
				break;
			}
		}
	}

	trash.ClearList();
}
and this is how it's used:

Code: Select all

GarbageCollector<Entity>& EntityGC = GarbageCollector<Entity>::Inst();
Entity* test = EntityGC.Alloc();
//add components here
while(!quit)
{
  //Update
  //Render
  EntityGC.Collect();
}
//exit
I have no idea why this won't work. Everything except Dealloc and Collect work (even CleanUp). I didn't show dealloc because its the same as Collect without the trash loop. One thing I do know is that it freezes when it reaches the marked line where it deletes the entity.

Re: GarbageCollector freezes

Posted: Mon Jul 30, 2012 3:22 pm
by Nokurn
What do the locals look like when you step through this in a debugger? What is bIt->data.ptr when it crashes? If you step into the delete, is the issue the destructor? Try reducing the problem as much as possible (probably in a separate project), then walking through the entire execution of the test case so that you can actually see what's going on with the data.

The most immediate thing that comes to mind when I look at this code is that bIt->data.ptr may be an invalid pointer--it could be garbage, or it could be deleted more than once. Try setting it to NULL after deleting it and then checking to see if it's NULL before deleting.

I'd also suggest using STL unless you have a very specific reason to avoid it (working with a platform that has limited resources, etc).

Re: GarbageCollector freezes

Posted: Mon Jul 30, 2012 5:07 pm
by YourNerdyJoe
Unfortunatly the NULL thing didn't work. In Visual Studio I set breakpoints on every line in that function as well as when the entity is created to check its address. It definitly is the first time its being deleted and the pointer also correct.

Re: GarbageCollector freezes

Posted: Mon Jul 30, 2012 6:35 pm
by Nokurn
I don't think the problem is with the code shown here, then. If you can create a sufficiently reduced version of the problem and would be comfortable sharing it, I could take a closer look.

Re: GarbageCollector freezes

Posted: Mon Jul 30, 2012 9:16 pm
by YourNerdyJoe
For some reason it works fine if I call dealloc at the beginning of the program but as soon as it gets to the main loop it doesn't want to work. After the loop also works fine, think it's something to do with my updater. I think I'll try something different to fix the problem this was suppose to which was make sure that all of the entities get deleted at the end of the program. Any theories you might have on how to do this would help.

Re: GarbageCollector freezes

Posted: Mon Jul 30, 2012 10:42 pm
by Nokurn
What type of error message are you getting when it crashes? Are you sure it's not crashing in the Entity destructor?

If you're using any reasonably recent compiler (at least Visual Studio 2010, GCC 4.6, or Clang 2.9 with libc++ if you want to avoid iffy behavior) you could use std::shared_ptr instead of writing a whole garbage collector. Then you wouldn't even need a list of entities if you don't want one.

Re: GarbageCollector freezes

Posted: Tue Jul 31, 2012 1:07 pm
by YourNerdyJoe
Yeah it was in the Entity destructor, when it deletes it components. When the Components are deleted they also have to remove their pointer from the Updater so it knows they've been deleted and something in there caused it to freeze (no error message, no crash, just stops). Good thing you mentioned those shared_ptrs Nokurn. I changed the list of components in the entity to a list shared_ptr<Component> and did the same thing for the Updater but with weak_ptrs. Didn't have to change anything in the GarbageCollector.

Re: GarbageCollector freezes

Posted: Tue Jul 31, 2012 1:57 pm
by Nokurn
Glad that it worked for you.

Educating the world about good pointer management seems to be my niche. *dons a cape and flies away*