[Solved] Clean memory allocation

Started by
24 comments, last by spudmuncher 15 years ago
Shouldn't your ClearAll function actually delete the elements in the vector?
Advertisement
True.
I've been trying to figure it out.
Whenever I delete an element, I get an error.
Nothing I do seems to help.

---------------------------
Microsoft Visual C++ Debug Library
---------------------------
Debug Assertion Failed!

Program: ...rojects\Vector Class Exercise\Debug\Vector Class Exercise.exe
File: d:\program files\microsoft visual studio 9.0\vc\include\vector
Line: 116

Expression: ("this->_Has_container()", 0)

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.

(Press Retry to debug the application)
---------------------------
Abort Retry Ignore
---------------------------

void ClearAll (){	List:: iterator i;	for (i=UpdateList.begin (); i!=UpdateList.end (); i++)	{		BaseUpdate * b = *(i);		delete b; // or b->DeleteMe();  The error is the same either way.	}	UpdateList.clear();}

I should think first then post.
Figured it out.

I didn't realize that i increments automatically when calling erase.

//Function for clearing the update listvoid ClearAll (){	List:: iterator i;	i = UpdateList.begin ();	while (i!=UpdateList.end ())	{		BaseUpdate * b = (*i);		i = UpdateList.erase (i); // increments i automatically		b->DeleteMe ();	}	UpdateList.clear();}
Quote:Original post by spudmuncher
I didn't realize that i increments automatically when calling erase.


The return value from erase() is an iterator to the next valid item in the container. This is done so that you can keep going with the iteration. When you erase an element, the iterator that referred to it is invalidated. Unusable. You cannot reliably dereference it, nor increment or decrement it. The iterator cannot be thought of in terms of storing an index into the list, and retrieving the index'th element on demand. It just doesn't work like that. It stores some unknown sort of information that allows it to get at an element, and traverse the container forward (and usually backward).
Quote:Original post by spudmuncher
b->DeleteMe ();

Why create a DeleteMe() function, while 'delete b;' does exactly the same - and also shows what really happens, rather than hiding it for the programmer? 'DeleteMe()' sounds like some sort of clean-up function, and while the name does signal something along the way of deleting the actual object, it's more confusing than a simple 'delete b;' statement. Things like this make maintenance a bit more trickier imho.
Create-ivity - a game development blog Mouseover for more information.
I have made all the adjustments for your concerns.

So thx a lot for all your help. (:

Here's my finished code for anyone else who wants something similar.

#include <iostream>#include <vector> // needed for the list#include <algorithm> // needed for the find functionusing namespace std;// number of Example classes createdstatic unsigned int n_Example = 0;//Base for all auto-updted classesclass BaseUpdate{public:	BaseUpdate () {}	virtual ~BaseUpdate ();	virtual void Update () = 0; // must define this function in derived classes	void DeleteMe () {delete this;} // used internally, you can just simply use  delete class;};//Example classclass Example : public BaseUpdate{	int number; // just for demo purposespublic:	Example (int num)   { ++n_Example; number = num; } // all these are inline, but they don't have to be	~Example ()		      { --n_Example; }	void Update ()      {cout << ": Updating Example" << endl; number++; }	int GetNumber ()    { return number; }};//List of auto-updted classestypedef vector <BaseUpdate *> List; // DONT PUT IN HEADERList UpdateList;//Function for creating example classExample * CreateExample (int number){	cout << " An example has been created!" << endl;	Example * b = new Example (number);	UpdateList.push_back (b); // add to list	return b;}Example * CreateExample () // no params{	cout << " An example has been created!" << endl;	Example * b = new Example (0);	UpdateList.push_back (b);	return b;}//When the class is destroyedBaseUpdate:: ~BaseUpdate (){	cout << "An example has been deleted!" << endl;	List:: iterator i;	i = find (UpdateList.begin (), UpdateList.end (), this); // find the current class in the list	if (i != UpdateList.end ()) UpdateList.erase (i);}//Function for auto-uptding the classesvoid Run (){	//Update the classes	List:: iterator i; // think of this as if it were int i;  but you can get the value from the list by *(i)	for (i=UpdateList.begin (); i!=UpdateList.end (); i++)	{		BaseUpdate * b = *(i);		b->Update ();	}}//Function for clearing the update listvoid ClearAll (){	List:: iterator i;	i = UpdateList.begin ();	while (i!=UpdateList.end ())	{		BaseUpdate * b = (*i);		i = UpdateList.erase (i); // increments i automatically		b->DeleteMe ();	}	UpdateList.clear(); //Doesn't really do anything, but o well}int main (){	Example *example1, *example2;	// Create a couple of thingys	example1 = CreateExample (5); // the number is an example of using a parameter	example2 = CreateExample (3);	// Record their numbers	cout << " example1 has this number value: " << example1->GetNumber () << endl;	cout << " example2 has this number value: " << example2->GetNumber () << endl;	// Automatically update (number++) all created Example classes	Run (); //This would normally be done in the main loop, but we don't have a main loop in this example	delete example1; //It's simple to delete stuff	example1 = CreateExample ();		// what are the new values	cout << " example1 has this number value: " << example1->GetNumber () << endl;	cout << " example2 has this number value: " << example2->GetNumber () << endl;		system ("PAUSE");		ClearAll ();	return 0;}

This topic is closed to new replies.

Advertisement