Sign in to follow this  
Uphoreum

std::map iteration

Recommended Posts

Uphoreum    216
Okay, I'm using an std::map to store image pointers that are associated with id numbers. So, if you reference "1" it will reference the image that is associated with "1". It is part of a class and I want to have a method that will free all the images from memory. The way that it is now, someone could have image "1" and image "5". If it were an std::vector, I could just use a for loop to cycle through until the iterator was larger than the size of the vector, but I'm not sure that this is the case with a map, because you reference the item by it's association key, not it's number in the list. So... I don't think I worded this post too well, but basically, how can I cycle through an std::map without using the "key" value, but instead, just iterate through all the items?

Share this post


Link to post
Share on other sites
Agony    3452
By using iterators, a concept that is common to all the SC++L's containers, and is very important for the generic algorithms and such. Iterators act a lot like pointers, in that you can dereference them (* or ->) to get what they refer (point) to. (In the case of std::map and std::multi_map, the container actually contains a set of std::pair<key, value>, rather than just values, so you dereference it and access first to get the key, or access second to get the value.)

std::map<std::string, image*> imageMap;

//fill in imageMap with images...

//then to erase everything:

std::map<std::string, image*>::iterator imageIterator;
for (imageIterator = imageMap.begin(); imageIterator != imageMap.end(); ++imageIterator)
{
delete imageIterator->second;
}
imageMap.clear();



However, I would recommend using some form of smart pointers (perhaps boost::shared_ptr) instead of using raw pointers. Then all you need to do is remove elements from the map, and never explicitly delete them. Much nicer that way.

Share this post


Link to post
Share on other sites
Spoonbender    1258
Iteration is done with iterators. Hence the name. [wink]

All containers in the C++ standard library supply iterators.

So basically, you'd do something like this:
for (<type of your map>::iterator it = mymap.begin(); it != mymap.end(); ++it){
// Do stuff here
}

That works for maps, strings, vectors, sets and whatever other container you can think of.

Share this post


Link to post
Share on other sites
rip-off    10979
How to iterate over a std::container?

Why, using an iterator of course [smile].


typedef std::map<int,SomeType*> SomeTypeMap;

SomeTypeMap someTypeMap;
addStuffToMap(someTypeMap);

for( SomeTypeMap::iterator it = someTypeMap.begin() ; it != someTypeMap.end() ; ++it )
{
delete it->second;
}
someTypeMap.clear();



Or we could use boost::shared_ptr:

typedef std::map<int,boost::shared_ptr<SomeType> > SomeTypeMap;

SomeTypeMap someTypeMap;
addStuffToMap(someTypeMap);

someTypeMap.clear();

Share this post


Link to post
Share on other sites
nobodynews    3126
with an iterator of course!
I believe this is the syntax:

std::map<int, std::string> lookUpTable;
// fill the look up table
for(std::map<int, std::string>::iterator i = lookUpTable.begin(); i != lookUpTable.end(); ++i)
{
// do stuff
}



edit: Jinx (for rip-off)

You guys are fast

Share this post


Link to post
Share on other sites
rollo    366
you can do it with normal iterators, its just that the values are going to be a std::pair, in your case I guess std::pair<std::string, Image*>, I prefer to use stl algorithms for stuff like this. here is an example using for_each:



// functor that deletes the second part of an image pair.
struct DeleteImage {
void operator() (MyClass::ImageMap::value_type p) {
delete p.second;
}
};

class MyClass {
public:
// or whatever it is you have, typedefs are nice so you dont
// have to repeat yourself
typedef std::map<std::string, Image*> ImageMap;

~MyClass() {
// clean up all images
std::for_each(images.begin(), images.end(), DeleteImage());
}

private:
ImageMap images;
};





Hopefully thats ok, I just typed it in, no testing ;)
DeleteImage can be made more general too with templates so if you need to do this often it can be reused.

[Edited by - rollo on May 6, 2007 4:28:31 PM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this