简体   繁体   中英

How can I erase a key value pair in c++ map?

I'm working on a project that needs unique keys and values so I decided to use maps. Everything works expect for the case where someone may want to change the key value. I'm not sure why, but it causes a fragmentation fault. Can I not do this?

void Journal::set_id(int id){               // journal class
    if(join.count(id)){                     // join is: static map <int,string> join
        cout<<"Journal ID is already being used. Try again."<<endl;
    }
    else {
        join.erase (join.find(id));
        join.insert(pair<int,string>(id,name));
    }
}

Your logic is flawed.

void Journal::set_id(int id){
    if(join.count(id)){
        cout<<"Journal ID is already being used. Try again."<<endl;
    }
    else {
        // When you hit this block of the code, there is nothing
        // in the map corresponding to 'id'.
        // join.find(id) returns the same iterator as join.end()
        // Calling erase() with that iterator is causing you the
        // problem.

        // Don't call erase. Just insert the new item.
        // join.erase (join.find(id));
        join.insert(pair<int,string>(id,name));
    }
}

You have just checked to make sure that id is not being used as a key in the map. If it is, you issue an error. So now you know that id is not in the map. If id is not in the map, join.find(id) will return join.end() , so you really didn't need to call find at all. But more importantly, you then call join.erase(join.end()) , which is an error.

See documention for std::map::erase() in cppreference :

The iterator pos must be valid and dereferenceable. Thus the end() iterator (which is valid, but is not dereferencable) cannot be used as a value for pos.

Rather than check whether the key is present, and insert it only if not found, you can simplify the code by just inserting the item, and then checking the return value to see if the insertion succeeded (which it won't if that key was already present).

void Journal::set_id(int id){
    if (!(join.insert(std::make_pair(id, name)).second))
        cout<<"Journal ID is already being used. Try again."<<endl;
}

This should also improve speed, since it only searches the tree once whereas code doing a count then an insert has to search it twice.

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