Skip to main content
GameDev.net gamedev.net
🔒 Locked

std::vector pointer deletion

Started by ISOPimp Dec 13, 2002 at 6:12 PM 8 replies 250+ views
Original Post
ISOPimp
ISOPimp
Sorry if this has been posted before but I tried a few examples given to me and they are not working. Here is my code that I am using to dynamically create some objects, display them, then delete them. The CEntity class has a copy constructor and overloaded operator= implemented.
  #include <iostream>
#include <string>
#include <vector>
#include "Entity.h"

using namespace std;
int main(int argc, char* argv[])
{
	vector<CEntity *>				vEnt;
	vector<CEntity *>::iterator	it;
	int							entity;
	string						name;

	cout<<"How many entities would you like?: ";
	cin>>entity;
	if(entity < 1 || entity > 255)
		entity = 1;
	cin.ignore(256, ''\n'');

	CEntity *pObj;
	for(int i=0; i<entity; ++i)
	{
		cout<<"Please enter a name for entity #"<<i+1<<": ";
		getline(cin, name, ''\n'');
		pObj = new CEntity(name);
		vEnt.push_back(pObj);
	}

	for(it = vEnt.begin(); it != vEnt.end(); it++)
	{
		pObj = *it;
		cout<<"Entity''s Name: "<<pObj->Name()<<endl;
	}

	//deallocation

	it=vEnt.begin();
	for(int i=0; it < vEnt.end(); i++)
	{
		delete vEnt[i];
	}
	return 0;
}  
At deallocation, I get access violations and I am not sure how I would properly delete my objects. Anyone got any suggestions? Also, while I am asking questions, is there a way to get the position int the vector the iterator is at?
Fruny
Fruny

for(int i=0; it < vEnt.end(); i++)
{
delete vEnt[ i ];
}


std::vector<CEntity *>::end() is not an int but a std::vector<CEntity *>::iterator.

You probably meant to use std::vector<CEntity *>::size().


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib ]

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
gmcbay
gmcbay
He could also get away with his loop mostly as is if he incremented the iterator. If the it iterator is never incremented, the loop will keep going 'forever'..or until it crashes from deleting the same allocated memory twice, whichever comes sooner (I'd bet on the latter).



  
for(int i=0; it < vEnt.end(); i++, ++it)
{
delete vEnt[i];
}


However, I'm not sure why he's even using i here, I'd just loop on the iterator ala


  
for(it = vEnt.begin(); it < vEnt.end(); ++it)
{
delete (*it);
}



[edited by - gmcbay on December 13, 2002 7:49:23 PM]
gmcbay
gmcbay
Annonymous...erase/clear won''t delete the memory at the pointer the container is holding though. So if you just erase() those elements from the vector the objects will still be in memory..memory leak at exit.

And in this example, there''s really no need to erase/clear out the vector, that will be handled when it goes out of scope. But the pointers to CEntity objects must be deleted to avoid a leak.



ISOPimp
ISOPimp
for(it = vEnt.begin(); it != vEnt.end(); it++)
{
delete (*it);
}

This worked. Thank you. I looked at two tutorials and they both told me different/wrong ways of doing it.


Any answer on the iterator position? I want something like:

cout<<"Element at position "<<iterator.position()<<" has value: "<<(*iterator)->Name()<<endl;

iterator.position() doesn''t exist (i dont think) but I would like something that could tell me the position of the iterator as it iterates.

Thanks again.
Fruny
Fruny
quote:
Original post by ISOPimp
Any answer on the iterator position?



distance( vEnt.begin(), itor );




[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib ]

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
gmcbay
gmcbay
When using iterator 'positions' keep in mind that holding onto that in your own code may be very dangerous because the data inside the container might rearrange itself (less likely on a vector, but pretty common when you insert a new item in mid-list on one of the linked list containers). If this happened you'd be holding on to a position handle that no longer points to what you think it does.

Any specific reason why you're looking to do this? If I know what you want to do this for, maybe I can suggest an alternative method of doing the same thing.


[edited by - gmcbay on December 13, 2002 8:06:39 PM]
ISOPimp
ISOPimp
Fruny: Thanks again.

gmcbay: Im just curious, that''s all. Look at my pseudo-example above. That is the extent I will be using it, just so I can differentiate between the elements.

You guys have helped a lot. Thank you.
Qw3r7yU10p!
Qw3r7yU10p!
you can use the standard algorithm functions to replace a lot of the work that is normally done in loops.

so for_each is a function that loops over every element in the container (it doesn't have to be a vector, anything that satisfies the requirements for a standard container will work with it)

for_each(vEnt.begin(), vEnt.end(), func)

func is a pointer to a function which takes a CEntity* as a parameter. func can do whatever it wants to the entity object.

So if func was defined as

    
void OutputName(CEntity* ent) {
cout << "Entity's Name: " << ent->Name() <<endl;
}


then that would achieve what you want. You could also use a function object and pass that in place of func.

There are various clever ways of calling member functions directly so that you don't have to define the 'func' function just for this small purpose. Boost.org has some useful stuff to help get it all working.

[edited by - petewood on December 14, 2002 4:50:39 PM]

Topic Locked

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

Sign in to reply to this topic.