简体   繁体   中英

Cyclically iterating through C++ map, program crashes

I am new to SO. I am new to iterators (or rather STL) in C++. I am trying to iterate through the keys of a map in a cyclic manner. So, we start reading from the start, proceed onto the end, and then go back to the start again. The code below is a simplification of the relevant portion of my program:

#include<iostream>
#include<map>
using namespace std;

int main(int argc, char* argv[])
{
    map<const char*, int> colors;

    colors  = { {     "RED", 1 },
                {  "YELLOW", 2 },
                {   "GREEN", 3 },
                {  "ORANGE", 4 },
                {    "CYAN", 5 } };

    map<const char*, int>::iterator itr = colors.begin();
    for(int i=0; i<10; i++)        // Loop more than entries in map
    {
        cout<<itr->first<<endl;

        if(itr==colors.end())
            itr = colors.begin();  //start from beginning
        else
            itr++;
    }

    return 0;
}

My program (and the above program) keeps crashing after iterating through the map once. I am not able to figure out why. I tried looking up on SO and elsewhere and couldn't find a solution.

Thanks in advance.

Think about what the iterator points to for each go around the loop.

When the iterator becomes equal to colors.end() , it doesn't point to anything and you're not allowed to dereference it.

But you dereference the iterator ( itr->first ) before you check whether it is equal to colors.end() .

See comments:

for(int i=0; i<10; i++) {
    std::cout << itr->first << std::endl;//Problematic..
    if(itr == colors.end())
        itr = colors.begin();  
    else
        itr++;                           //If this increment results to an `end()` iterator  
}

You are unconditionally accessing the iterator without checking if it's an end() iterator. You should check that the iterator isn't an end() iterator before you access the element it points to.

You can change your loop to:

for(int i=0; i<10; i++){        // Loop more than entries in map
    if( itr != colors.end() ){
        std::cout<< itr->first << std::endl;
        ++itr;
    }
    else
         itr = colors.begin();  //start from beginning
}

Demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM